何时使用 Unicode 规范化表格 NFC 和 NFD?

Posted

技术标签:

【中文标题】何时使用 Unicode 规范化表格 NFC 和 NFD?【英文标题】:When to use Unicode Normalization Forms NFC and NFD? 【发布时间】:2013-04-05 20:07:17 【问题描述】:

Unicode Normalization FAQ 包括以下段落:

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

然后继续……

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

我的问题是:

什么使 NFC 最适合“一般文本”。什么定义了“内部处理”,为什么最好留给 NFD?最后,不管什么是“最好的”,只要使用相同的规范化形式比较两个字符串,这两种形式是否可以互换?

【问题讨论】:

«NFC 是一般文本的最佳形式,因为它与从传统编码转换的字符串更兼容。 ... NFD 和 NFKD 对内部处理最有用。»是一些虚假的陈述。虽然遗留字符串可能以一种在转换为 Unicode 时为 NFC 形式的形式出现,但为了将来的维护(代码总是最终在不可预见的情况下使用),如果你明确地转换为 NF[CD],你会更好。 【参考方案1】:

FAQ 有点误导,首先是使用“应该”,然后是对同一事物的不一致使用“要求”。 Unicode 标准本身(在常见问题中引用)更准确。基本上,您不应期望程序将规范等效的字符串视为不同,但也不应期望所有程序都将它们视为相同。

在实践中,这实际上取决于您的软件需要做什么。在大多数情况下,您根本不需要进行归一化,归一化可能会破坏数据中的基本信息。

例如,U+0387 GREEK ANO TELEIA (·) 被定义为等同于 U+00B7 MIDDLE DOT (·) 的规范。这是一个错误,因为字符非常不同,并且在处理过程中应该以不同的方式呈现和处理。但改变这一点为时已晚,因为 Unicode 的这一部分已经刻在石头上。因此,如果您将数据转换为 NFC 或以其他方式丢弃规范等效字符串之间的差异,则可能会遇到错误字符。

标准化会带来风险。例如,字母“ä”可以显示为单个 Unicode 字符 U+00E4 带有分音符号的拉丁小写字母 A,也可以显示为两个 Unicode 字符 U+0061 拉丁小写字母 A U+0308 组合分音符号。它将主要是前者,即预先组合的形式,但如果是后者并且您的代码仅使用预先组合的形式测试包含“ä”的数据,那么它将不会检测到后者。但在许多情况下,您并没有做这些事情,而只是简单地存储数据、连接字符串、打印它们等。那么这两种表示可能会导致呈现略有不同的风险。

您的软件是否以某种方式将字符数据传递给其他软件也很重要。由于幼稚的隐含假设或有意识地并以记录的方式,接收者可能期望其输入被规范化。

【讨论】:

在 Max OS X 文件名中,U+0061 LATIN SMALL LETTER A U+0308 COMBINING DIAERESIS 可以用来表达“ä”,这需要特定版本的 NFD。 @hippietrail 是否记录在某处? @Keith4G:应该有关于它的问题。让我看看你。我不是 Mac 用户,但几年前我做了一些东西来阅读 Mac 分区,然后遇到了这个问题。 Technical Note TN1150 / HFS Plus Volume Format /Unicode Subtleties 我在查找有关 OS X 规范化的具体信息时遇到了麻烦。谢谢【参考方案2】:

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

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

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

    这是你的意思吗?

【讨论】:

Re 3,我认为情况并非总是如此。例如。 (来自***)字符串 1 包含“U+212B”(埃符号“Å”),字符串 2 包含“U+0041 U+030A”(拉丁字母“A”和“°”上方的组合环)。在 NFD 下,它们是等价的,但在 NFC 下,字符串 2 转换为“U+00C5”(瑞典字母“Å”),因此两者不等价。在我看来,NFD 是最安全的选择。 en.wikipedia.org/wiki/Unicode_equivalence#Normal_forms @Aurimas 来自 unicode 网站unicode.org/reports/tr15/tr15-18.html 你说得对,在阅读了有关此问题的更多信息后,我正要更改我的评论。这里的关键是,要使用 NFC,您首先要转换为 NFD。

以上是关于何时使用 Unicode 规范化表格 NFC 和 NFD?的主要内容,如果未能解决你的问题,请参考以下文章

哪个是更好的 Unicode 规范化形式?

发送 POST 数据时阻止 Safari 规范化 Unicode?

NFC 服务具体何时停用?

何时使用 CouchDB 与 RDBMS [关闭]

出示 NFC 卡时触发事件

File.listFiles() 使用 JDK 6 破坏 unicode 名称(Unicode 规范化问题)