Log*_*phy 3 java utf-16 kotlin
我正在尝试迭代以下字符串:
\nm\xc9\x94\xcc\x83tr
\n但无论我做什么,它总是最终被处理为:
\n米 \xc9\x94 \xcc\x83 tr
\n波形符似乎与反转的 c 分离。
\n我的第一个尝试是执行以下操作:
\n"m\xc9\x94\xcc\x83tr".map {\n print(it)\n}\nRun Code Online (Sandbox Code Playgroud)\n但波形符不会与反转的 c 保持一致。
\n我看到了以下迭代器的建议:
\nfun codePoints(string: String): Iterable<String> {\n return object : Iterable<String> {\n override fun iterator(): MutableIterator<String> {\n return object : MutableIterator<String> {\n var nextIndex = 0\n override fun hasNext(): Boolean {\n return nextIndex < string.length\n }\n\n override fun next(): String {\n val result = string.codePointAt(nextIndex)\n nextIndex += Character.charCount(result)\n return String(Character.toChars(result))\n }\n\n override fun remove() {\n throw UnsupportedOperationException()\n }\n }\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n但这给出了与前面的示例相同的输出。
\n我已经被这个看似简单的问题困扰了一天,我只想处理这个字符串,就好像它有 4 个字符,而不是 5 个字符一样。
\n有小费吗?
\nSwe*_*per 11
“\xc9\x94\xcc\x83”由两个Unicode 代码点组成。这就是为什么您显示的代码点迭代器仍然将 \xc9\x94\xcc\x83 视为单独的。
\n“\xc9\x94\xcc\x83”是单个字素簇。要迭代这些,您需要一个java.text.BreakIterator. 在文档中,有一个示例向您展示了如何操作。
public static void printEachForward(BreakIterator boundary, String source) {\n int start = boundary.first();\n for (int end = boundary.next();\n end != BreakIterator.DONE;\n start = end, end = boundary.next()) {\n System.out.println(source.substring(start,end));\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n在 Kotlin 中,您可以编写一个扩展函数来String返回一个Sequence字素簇。
fun String.graphemeClusterSequence() = sequence {\n val iterator = BreakIterator.getCharacterInstance()\n iterator.setText(this@graphemeClusterSequence)\n var start = iterator.first()\n var end = iterator.next()\n while (end != BreakIterator.DONE) {\n yield(this@graphemeClusterSequence.substring(start, end))\n start = end\n end = iterator.next()\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n现在"m\xc9\x94\xcc\x83tr".graphemeClusterSequence().forEach { println(it) }打印:
m\n\xc9\x94\xcc\x83\nt\nr\nRun Code Online (Sandbox Code Playgroud)\n