如何判断Unicode代码点是否是一个完整的可打印字形(或字形簇)?

时间:2018-08-23 22:06:32

标签: java c# unicode glyph codepoint

我们假设有一个Unicode String对象,我想一一打印该String中的每个Unicode字符。 在我使用非常有限的语言进行的简单测试中,只要假设一个代码点始终与一个字形相同,我就可以连续实现这一目标。

但是我知道情况并非如此,并且上面的代码逻辑可能会在某些国家或语言中轻易导致意外结果。

所以我的问题是,有没有办法判断一个Unicode代码点是Java还是C#中的一个完整的可打印字形? 如果我必须用C / C ++编写代码,那也很好。

我在Google上搜索了几个小时,但所得到的只是关于代码单位和代码点的信息。很容易分辨出代码单元是否是代理对的一部分,而对字素却一无所知。

有人可以指出我的正确方向吗?

1 个答案:

答案 0 :(得分:2)

您绝对正确,单个字形通常由多个代码点组成。例如,字母é(带有重音符号的e)可以等效地写成\u00E9或带有重音符号的\u0065\u0301。 Unicode normalization不能总是将这样的事情合并到一个代码点中,尤其是在存在多个组合字符的情况下。因此,您需要使用一些Unicode分段规则来确定所需的边界。

您所说的“可打印字形”称为user-perceived character或(extendedgrapheme 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);
}