Unicode规范化
Unicode规范化(Unicode Normalization)是把「看起来相同、含义也相同,但底层码点序列不同」的文本,转换成统一形式的过程。例如 é 既可以是单个码点 U+00E9,也可以是 e(U+0065)加上一个组合尖音符 U+0301。二者视觉一致、语义等价,但字节不同,直接比较会被判为「不相等」。规范化就是消除这种歧义,让等价文本能正确地比较、搜索和去重。
Unicode 定义了四种规范化形式:
NFD:正规分解,把预组合字符拆成「基字符 + 组合记号」。NFC:先分解再重组为预组合形式,是 Web 及多数场景推荐的默认形式。NFKD/NFKC:兼容分解 / 重组,会把fi连字、全角字符、带圈数字①等「兼容字符」归并为普通形式。
使用要点与常见误区:NFC/NFD 是无损、可逆的(规范等价);而 NFKC/NFKD 是有损的(兼容等价),会丢失格式区分,多用于搜索匹配而不适合存储原文。此外,规范化不等于「大小写折叠」,也不等于「去除重音」——去除重音(如本站 remove-accents 工具)通常是先做 NFD 分解,再删掉组合记号(U+0300–U+036F)。规范化后字符串的码点长度可能变化,别假设它保持不变。
常见问题
NFC 和 NFD 有什么区别?
NFD 把字符分解成「基字符 + 组合记号」,NFC 则在分解后再重组为尽量少的预组合码点。两者规范等价、可互相转换;Web 上通常推荐使用 NFC。
规范化能直接用来去除重音符号吗?
不能直接去除,但它是关键的第一步。常见做法是先用 NFD 分解,把重音拆成独立的组合记号,再删除这些记号(U+0300–U+036F),就得到无重音的字母。
带 K 的 NFKC/NFKD 和普通形式有何不同?
带 K 的是「兼容」形式,会把全角字符、连字(如 fi)、上标或带圈数字等归并为普通字符,属于有损转换。它适合搜索匹配,但不建议用来存储原文,以免丢失信息。