Unicode Normalization FAQ包括以下段落:
程序应始终将规范等效的Unicode字符串视为相等... Unicode标准提供了可用于此的明确定义的规范化形式:NFC和NFD。
并继续......
使用哪种选择取决于特定的程序或系统。 NFC是一般文本的最佳形式,因为它与从传统编码转换的字符串更兼容。 ...... NFD和NFKD对内部处理最有用。
我的问题是:
什么使NFC成为“一般文本”的最佳选择。什么定义“内部处理”,为什么最好留给NFD?最后,只要使用相同的规范化形式比较两个字符串,两个形式可以互换,从不关注什么是“最佳”?
答案 0 :(得分:8)
常见问题解答有点误导,从使用“应该”开始,然后是对同一事物的“要求”的不一致使用。 Unicode标准本身(在FAQ中引用)更准确。基本上,您不应期望程序将规范等效的字符串视为不同的字符串,但您也不应期望所有程序都将它们视为相同。
实际上,它实际上取决于您的软件需要做什么。在大多数情况下,您根本不需要进行标准化,标准化可能会破坏数据中的基本信息。
例如,U + 0387 GREEK ANO TELEIA(·)被定义为规范等效于U + 00B7 MIDDLE DOT(·)。这是一个错误,因为角色非常独特,应该以不同的方式呈现,并在处理过程中区别对待。但改变这一点为时已晚,因为Unicode的这一部分已被刻入石头。因此,如果您将数据转换为NFC或以其他方式丢弃规范等效字符串之间的差异,则可能会出现错误字符。
不规范化会带来风险。例如,字母“ä”可以显示为单个Unicode字符U + 00E4 LATIN SMALL LETTER A WITH DIAERESIS或两个Unicode字符U + 0061 LATIN SMALL LETTER A U + 0308 COMBINING DIAERESIS。它主要是前者,即预组合形式,但如果它是后者并且你的代码测试包含“ä”的数据,仅使用预组合形式,那么它将不会检测后者。但在许多情况下,你不会做这些事情,只是简单地存储数据,连接字符串,打印它们等等。然后存在这两种表示导致某些不同渲染的风险。
您的软件是否以某种方式将字符数据传递给其他软件也很重要。由于天真的隐含假设或者有意识地并且以文档化的方式,接收者可能期望其输入被标准化。
答案 1 :(得分:3)
NFC是您应该使用的一般常识形式,ä
在那里是1个代码点,这是有道理的。
NFD适用于某些内部处理 - 如果您想进行不区分重音的搜索或排序,在NFD中使用您的字符串会使其更容易,更快捷。另一种用法是制作更强大的slug游戏。这些只是最明显的,我相信还有很多用途。
如果两个字符串x和y是规范等价物,那么
toNFC(x)= toNFC(y)
toNFD(x)= toNFD(y)
这是你的意思吗?