我们假设有一个Unicode String
对象,我想一一打印该String
中的每个Unicode字符。
在我使用非常有限的语言进行的简单测试中,只要假设一个代码点始终与一个字形相同,我就可以连续实现这一目标。
但是我知道情况并非如此,并且上面的代码逻辑可能会在某些国家或语言中轻易导致意外结果。
所以我的问题是,有没有办法判断一个Unicode代码点是Java还是C#中的一个完整的可打印字形? 如果我必须用C / C ++编写代码,那也很好。
我在Google上搜索了几个小时,但所得到的只是关于代码单位和代码点的信息。很容易分辨出代码单元是否是代理对的一部分,而对字素却一无所知。
有人可以指出我的正确方向吗?
答案 0 :(得分:2)
您绝对正确,单个字形通常由多个代码点组成。例如,字母é(带有重音符号的e)可以等效地写成\u00E9
或带有重音符号的\u0065\u0301
。 Unicode normalization不能总是将这样的事情合并到一个代码点中,尤其是在存在多个组合字符的情况下。因此,您需要使用一些Unicode分段规则来确定所需的边界。
您所说的“可打印字形”称为user-perceived character或(extended)grapheme cluster。在Java中,迭代这些方法的方法是使用BreakIterator.getCharacterInstance(Locale)
:
BreakIterator boundary = BreakIterator.getCharacterInstance(Locale.WHATEVER);
boundary.setText(yourString);
for (int start = boundary.first(), end = boundary.next();
end != BreakIterator.DONE;
start = end, end = boundary.next()) {
String chunk = yourString.substring(start, end);
}