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

How can I tell if a Unicode code point is one complete printable glyph(or grapheme cluster)?

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

但我知道并非如此,上面的代码逻辑在某些国家或语言中很容易造成意想不到的结果。

所以我的问题是,在 Java 或 C# 中,有什么方法可以判断一个 Unicode 代码点是否是一个完整的可打印字形? 如果我必须在 C/C++ 中编写代码,那也没关系。

我在谷歌上搜索了几个小时,但我得到的只是关于代码单元和代码点的信息。很容易判断一个代码单元是否是代理对的一部分,但与字素无关..

谁能给我指出正确的方向,好吗?

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

你所说的 "printable glyph" 被称为 user-perceived character or (extended) grapheme cluster. In Java, the way to iterate over these is with 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);
}