何时使用Unicode规范化形式NFC和NFD?

时间:2013-04-13 08:37:12

标签: string unicode normalization unicode-normalization

Unicode Normalization FAQ包括以下段落:

  

程序应始终将规范等效的Unicode字符串视为相等... Unicode标准提供了可用于此的明确定义的规范化形式:NFC和NFD。

并继续......

  

使用哪种选择取决于特定的程序或系统。 NFC是一般文本的最佳形式,因为它与从传统编码转换的字符串更兼容。 ...... NFD和NFKD对内部处理最有用。

我的问题是:

什么使NFC成为“一般文本”的最佳选择。什么定义“内部处理”,为什么最好留给NFD?最后,只要使用相同的规范化形式比较两个字符串,两个形式可以互换,从不关注什么是“最佳”?

2 个答案:

答案 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)

  1. NFC是您应该使用的一般常识形式,ä在那里是1个代码点,这是有道理的。

  2. NFD适用于某些内部处理 - 如果您想进行不区分重音的搜索或排序,在NFD中使用您的字符串会使其更容易,更快捷。另一种用法是制作更强大的slug游戏。这些只是最明显的,我相信还有很多用途。

  3.   

    如果两个字符串x和y是规范等价物,那么
      toNFC(x)= toNFC(y)
      toNFD(x)= toNFD(y)

    这是你的意思吗?