我正在开发一个需要生成“不区分大小写”的规范化形式的 Unicode 文本的 C 项目。我选择将规范化形式定义为首先转换为规范化形式 NFD,然后应用 Unicode 大小写折叠算法,最后将结果转换为 Unicode 规范化形式 NFC。
我依靠 ICU 的 C API 来实现其 Unicode 表示和实用功能,使用 ICUunorm_normalize()
和u_strFoldCase()
功能实现我的方案相当简单。但是我的一项测试失败了,我不明白为什么。ICU 似乎正在生成与我预期不同的 NFC 形式。
输入序列由以下 BMP 代码点组成:
U+0020, U+1EA5, U+0328, U+1EC4, U+031C
通过调试器,我确定 ICU 和我同意案例折叠后的中间结果:
U+0020 U+0061 U+0328 U+0302 U+0301 U+0065 U+031C U+0302 U+0303
请特别注意,早期转换为 NFD 的形式将字符 U+031C 移动到 U+1EC4 分解的中间,这取决于所涉及字符的相对 CCC 编号。这是我正在尝试测试的一部分。
现在好的部分:根据 ICU,折叠字符序列的 NFC 规范化是
U+0020 U+0105 U+0302 U+0301 U+1ec5 U+031C
而我认为应该是
U+0020 U+0105 U+0302 U+0301 U+0065 U+031C U+0302 U+0303
因为后面的三个组合字符已经是规范顺序了,不存在 U+0065 和 U+031C 的规范组合。
所以,两个问题:
- 哪个是正确的 NFC 形式?
- 如果ICU是正确的,那为什么?