我使用
Normalizer.normalize(url, Normalizer.Form.NFD)
是为了避免在我的网址中出现类似 é
的字符,并且我不明白 Normalizer.Form
常量(NFC、NFD、NFKC 和 NFKD)的含义或何时使用每一个。
有人对这个话题有任何想法吗?
提前致谢!
e
´
é
K 代表连字,一个字母
ffi
(ffi) 或 3:f f i。
这在javadoc中提到:
带重音符号或其他装饰的字符可以编码为多种 Unicode 中的不同方式。例如,以字符 A-acute 为例。在 Unicode,这可以编码为单个字符(“组合” 形式):
U+00C1 LATIN CAPITAL LETTER A WITH ACUTE
或作为两个单独的字符(“分解”形式):
U+0041 LATIN CAPITAL LETTER A U+0301 COMBINING ACUTE ACCENT
但是,对于程序的用户来说,这两个序列应该被视为相同的 “用户级”字符“带有锐音符号的A”。当你在寻找的时候 或比较文本,您必须确保这两个序列是 视为同等。此外,您必须使用以下方式处理字符 不止一种口音。有时角色的组合顺序 重音很重要,而在其他情况下重音序列 不同的命令实际上是等效的。同样,字符串“ffi” 可以编码为三个单独的字母:
U+0066 LATIN SMALL LETTER F U+0066 LATIN SMALL LETTER F U+0069 LATIN SMALL LETTER I
或作为单个字符
U+FB03 LATIN SMALL LIGATURE FFI
所以在你的情况下你想要 NFKD,完全分解。
s = Normalizer.normalize(s, Normalizer.Form.NFD).replaceAll("\\p{M}", "");
后者
replaceAll
只是删除了组合变音符号,零宽度重音符号´
。仍然存在有问题的拉丁字母,例如
ŀ
波兰语小 L 带删除线ı
土耳其小写 I 不带点İ
土耳其首都 I 带点但可能已经在进行非 ASCII 替换。
当然,现在人们可能在某种程度上拥有 Unicode URLs,即带有特殊字符的网站。 只要小心一些,这些角色就不会被损坏。
分解形式标准化的另一个用途是按字母顺序对国家/地区名称进行排序:
Österreich
(德语中的奥地利)位于 P
之前。
一些细节
K 代表“兼容性”,因此很重要。
一个字母可以有多个重音符号(零宽度组合变音符号)。
一个人可以拥有一个同时包含组合字母和分解字母的字符串。
实际上 NFC 的作用是:规范分解,然后是规范组合。因此,为了做出好的构图,最好首先分解,这会为您提供标准化器。
组合也有它的用处;例如,它保证规范(单一规范形式),并且对于
String.codePointAt
来说是紧凑的。