NFKD是否通过兼容性和规范等效来分解字符?



在多次尝试理解之后,我不得不说我不明白String.prototype.normalize()是如何工作的。该方法可以取NFCNFDNFKCNFKD作为参数。

首先,我不明白NFDNFKD的区别是什么。说明书对此非常模糊,所以……在一些资源中,我读到NFD通过规范等价来分解字符。例如:

"â" (U+00E2) -> "a" (U+0061) + " ̂" (U+0302)

NFKD按兼容性对字符进行分解。例如:

"fi" (U+FB01) -> "f" (U+0066) + "i" (U+0069)

但这并不完全正确。NFKD不仅根据兼容性分解字符。它还可以完美地处理第一个例子:

let s = `u00E2`; //"â" 
console.log(s.normalize('NFD').length); //2
console.log(s.normalize('NFKD').length); //2

这是否意味着NFKD可以通过兼容性和规范等价来分解字符?NFD只通过规范等价来分解字符…?

let s = `uFB01`; //"fi"
console.log(s.normalize('NFD').length); //1

Unicode

选择的完全分解类型取决于哪个Unicode涉及到归一化形式。对于NFC或NFD,一个人做一个完整的正则分解,它只使用正则Decomposition_Mapping值。对于NFKC或NFKD,一个人做一个完整的兼容性分解,它使用规范的和

这就是为什么NFC/NFD和NFKC/NFKD是这样工作的:

let s1 = 'uFB00'; //"ff"
let s2 = 'u0066u0066'; //"ff"
console.log(s1.normalize('NFD').length); //doesn't work with compatible -- only can. eq.
let t1 = `u00F4`; //ô
let t2 = `u006Fu0302`; //ô
console.log(t1.normalize('NFKD').length); //also works with can. eq.
console.log(t2.normalize('NFKC').length); //also works with can. eq.

这完全可以理解,因为…

MDN

所有标准等价序列也兼容,但反之则不兼容。

最新更新