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