通过逐个字符遍历Unicode代码点

7
我有一系列Unicode代码点。我真正需要做的是将这些代码点作为字符序列而不是代码点序列进行迭代,并确定每个单独字符的属性,例如是字母还是其他内容。
例如,想象一下我正在编写一个Unicode-aware文本框,用户输入了一个多于一个代码点的Unicode字符,例如“带变音符的e”。我知道这个特定字符也可以表示为一个代码点,并且可以规范化为该形式,但我认为在一般情况下这是不可能的。我如何实现退格?显然不能只删除最后一个代码点,因为他们可能刚刚输入了多个代码点。
我如何将一堆Unicode代码点迭代为字符?
编辑:ICU提供的断点迭代器似乎就是我需要的。但是,我没有使用ICU,所以任何关于如何实现自己的等效功能的参考都是可接受的答案。

另一个编辑:事实证明,Windows API确实提供了这个功能。MSDN只是没有很好地将所有字符串函数放在一起。CharNext就是我要找的函数。


在这个上下文中,你如何定义“字符”?是指可以转换为单个视觉字形的东西吗? - Nicol Bolas
1
除非你用代码点来定义字符,否则无法得出答案。Unicode只定义了两个东西:代码点和扩展字形簇。它并没有定义字符。请用代码点和/或扩展字形簇重新表述你的问题,或者精确定义术语以便能够实现编程解决方案,而你还没有这样做。 - tchrist
3
@tchrist:你真的需要在每个答案下都发表“同样”的评论吗?我只需读一次就明白了。 - Puppy
1
然而,我没有使用ICU。事实上,你应该使用它。毕竟这就是它的作用。为了完成BreakIterator的功能,你需要查询unicode点的属性,以确定是否可以在它们之间断开。这需要下载Unicode规范并构建不同属性的代码点范围表。或者你可以直接使用ICU,它会为你完成这一切。 - Nicol Bolas
2
@tchrist:这可能有点晚了,但根据Unicode标准版本6.2第11页的说法:“字符是书面语言最小组成部分的抽象表示,具有语义价值。它们主要代表,但不仅限于,构成自然语言文本和技术符号的字母、标点和其他符号。”该文档随后提供了一张表格,说明了字形和字符之间的区别。如果这不是一个定义,那我就不知道什么才是了。 - Talia
显示剩余4条评论
2个回答

5

值得花费这个精力吗?这些“带变音符的e”案例有多常见?请注意,我不知道,我只是在问。 - Johannes Schaub - litb
1
什么是字符?Unicode有代码点,其API刚刚被描述过,它还有可通过断句器或\X正则表达式元字符序列访问的扩展字形簇。 - tchrist
1
@tchrist:中断迭代器看起来不错。然而,我没有使用ICU,所以答案需要讨论其实现。诚然,“中断迭代器”不是我选择寻找此类功能的名称,所以我没有看到它。 - Puppy
2
即使在UTF-32中,代码点也不是字符。UTF-32处理代理对,但还有其他问题,如变音符号。请查看Unicode文本分段附录中的图形簇。 - André Caron
@AndréCaron 我是UTC的成员。我确实知道这些内容,但我认为OP并没有试图完全掌握它们。 - bmargulies
显示剩余2条评论

1

UTF8-CPP 项目有一堆干净易读的STL算法,可以逐个代码点、逐个字符等迭代Unicode字符串。你可以参考这个项目来获取灵感。

请注意,“逐个字符”的方法可能不是很明显。一个简单的方法是在规范化形式C下迭代UTF-32字符串,这保证了固定长度编码。


据我的理解,并不是所有字符都能以C形式表示。 - Puppy
1
不可能采用“逐个字符”的方法,因为“字符”没有被定义。 - tchrist
2
@tchrist:事实上,整个Unicode标准并没有定义“字符”这个术语。然而,有一个通常被接受的1个显示单位的定义,通常呈现为单个字形。这基本上对应于NFC中的完整预组合码点集。在NFC中使用UTF-32可以让您获得最接近每个码点的单个“字符”。 - André Caron
6
处于规范形式C并不意味着字符串中没有分解合并字符。它仅表示可以组合的序列已经组合了。如果存在尚未拥有自己合并代码点的模糊组合,则仍会在NFC字符串中找到组合字符。值得一提的是,已经存在覆盖越南语可能字母和音调标记的合并代码点。 - bobince
1
@tchrist:我在思考“用户感知字符”,这确实是由字形簇近似表示的 - André Caron
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接