什么是规范化的 UTF-8?你从来不想知道的关于Unicode规范化的所有信息

2022-08-30 06:58:22

ICU 项目(现在也有 PHP )包含帮助规范化 UTF-8 字符串所需的类,以便在搜索时更轻松地比较值。

但是,我试图弄清楚这对应用程序意味着什么。例如,在哪些情况下,我想要“规范等价”而不是“兼容性等价”,反之亦然?


答案 1

你从来不想知道的关于Unicode规范化的所有信息

规范规范化

Unicode 包含多种编码某些字符的方法,最明显的是重音字符。规范规范化将代码点更改为规范编码形式。生成的代码点应与原始代码点相同,除非字体或呈现引擎中存在任何错误。

何时使用

由于结果看起来相同,因此在存储或显示字符串之前对字符串应用规范化始终是安全的,只要您可以容忍结果不是与输入相同的位对位。

规范规范化有两种形式:NFD 和 NFC。从某种意义上说,两者是等价的,人们可以在这两种形式之间转换而不会丢失。在NFC下比较两个字符串将始终给出与在NFD下比较它们相同的结果。

断续器

NFD已将字符完全展开。这是计算速度更快的规范化形式,但结果是更多的码位(即使用更多的空间)。

如果您只想比较两个尚未规范化的字符串,这是首选的规范化形式,除非您知道需要兼容性规范化。

近场交通

NFC 在运行 NFD 算法后尽可能重新组合代码点。这需要更长的时间,但会导致字符串更短。

兼容性规范化

Unicode 还包括许多实际上不属于的字符,但这些字符在旧字符集中使用。Unicode 添加了这些字符,以允许将这些字符集中的文本作为 Unicode 进行处理,然后转换回来而不会丢失。

兼容性规范化将这些字符转换为相应的“真实”字符序列,并执行规范规范化。兼容性规范化的结果可能看起来与原始结果不同。

包含格式设置信息的字符将替换为不包含格式设置信息的字符。例如,字符转换为 .其他不涉及格式差异。例如,罗马数字字符转换为常规字母。9IX

显然,一旦执行了此转换,就不再可能无损地转换回原始字符集。

何时使用

Unicode 联盟建议将兼容性规范化视为转换。在某些情况下,它可能是有用的东西,但你不应该随意应用它。ToUpperCase

一个优秀的用例是搜索引擎,因为您可能希望搜索与 匹配 。9

您可能不应该做的一件事是显示对用户应用兼容性规范化的结果。

NFKC/NFKD

兼容性规范化形式有两种形式 NFKD 和 NFKC。它们与NFD和C之间的关系相同。

NFKC 中的任何字符串本质上也存在于 NFC 中,NFKD 和 NFD 也是如此。因此,和 等。NFKD(x)=NFD(NFKC(x))NFKC(x)=NFC(NFKD(x))

结论

如果有疑问,请使用规范规范化。根据适用的空间/速度权衡,或根据您正在与之交互的事物所需的内容,选择 NFC 或 NFD。


答案 2

某些字符,例如带有重音符号的字母(例如),可以用两种方式表示 - 单个码位或普通字母后跟组合重音符号。普通规范化将选择其中之一来始终表示它(NFC的单个码位,NFD的组合形式)。éU+00E9U+0065 U+0301

对于可以由多个基本字符序列和组合标记表示的字符(例如,“s,dot below,dot above”与将点放在上面然后点下面或使用已经具有其中一个点的基本字符),NFD还将选择其中一个(下面先去,因为它发生时)

兼容性分解包括许多字符,这些字符“不应该真正”是字符,而是因为它们在传统编码中使用。普通的规范化不会统一这些(以保持往返完整性 - 这对于组合形式来说不是问题,因为没有遗留编码(除了少数越南编码)同时使用),但兼容性规范化会。想想一些东亚编码中出现的“kg”千克符号(或半角/全角片假名和字母),或者MacRoman中的“fi”连字。

有关更多详细信息,请参阅 http://unicode.org/reports/tr15/


推荐