将带有表情符号的字符串映射为字符串数组或字符数组

6
我希望将我的字符串转换成字符串数组或字符列表,例如:Array<String>Array<Char>
示例:
val myText = "Ab+2#✅'ü{" // Parse and print to Log

应该:

[ "A", "b", "", "+", "", "2", "", "#", "✅", "'", "", "ü", "", "{" ] // Array contains Strings or Chars

因为 Android 上的表情符号而无法正常工作的 Java/ Kotlin 方法:

myText.toList() // ❌ Fails because of Emojis
myText.toMutableList() // ❌ Fails because of Emojis
2个回答

7
在Kotlin中,如果目标是JDK 8或更高版本,则可以使用:
fun String.splitToCodePoints(): List<String> {
    return codePoints()
        .toList()
        .map { String(Character.toChars(it)) }
}

如果使用JDK 7,则需要更多的手动操作:

fun String.splitToCodePoints(): List<String> {
    val list = mutableListOf<String>()
    var count = 0
    while (count < length) {
        with (codePointAt(count)){
            list.add(String(Character.toChars(this)))
            count += Character.charCount(this)
        }
    }
    return list
}

看起来 Kotlin 标准库在这些方面缺乏支持,因为你必须依赖于 JDK 包装的原始类将代码点整数转换为字符串。

如另一个答案所述,如果需要处理零宽连字符,则必须进行更多工作。您可能需要删除任何零宽连接器,以便可以单独显示字符,或者您可能想要将它们一起显示,因此需要操作列表以合并由连接器分隔的元素。如果语言使用连字号,这会影响此决定。


1
为了正确处理表情符号,您需要处理[字形簇](http://www.unicode.org/reports/tr18/#Default_Grapheme_Clusters)(请注意,这不仅是表情符号问题,甚至字母也可以由组合字符组成)。从Java 9开始,您可以使用Arrays.asList(myText.split("\\b{g}"))Pattern.compile("\\X").matcher(myText).results().map(MatchResult::group) .collect(Collectors.toList()) - Holger

4
在Java中,您可以获取字符串的代码点流,并将每个代码点转换回字符串:
var myText = "Ab+2#✅'ü{";
String[] array = myText.codePoints()
    .boxed()
    .map(i -> new String(Character.toChars(i)))
    .toArray(String[]::new)

返回:

{ "A", "b", "", "+", "", "2", "", "", "#", "✅", "'", "", "ü", "", "", "{" }

请注意,一些表情符号,比如旗帜、肤色和性别变化,是由多个Unicode代码点组合而成的,因此可能会产生您不想要的结果。

谢谢,你的回答很好,但它需要API级别24,而我的版本是21。 - A. Amini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接