→
その String を Unicode 正規化形式で処理した文字列を返します。
String | |||||||||
---|---|---|---|---|---|---|---|---|---|
form | 省略可。Unicode 正規化形式を示す "NFC"、"NFD"、"NFKC"、"NFKD" のうちの一つです。省略されたり undefined であったりした場合は "NFC" が使われます。
これらの値には以下の意味があります:
|
String。与えられた文字列の Unicode 正規化形式を含む文字列です。
Unicode は個々の文字に対して、コード ポイントと呼ばれる固有の値を割り当てています。例えば、"A" のコードポイントは U+0041 が割り当てられています。しかし、複数のコード ポイントや、コード ポイントの一連の並びが、同一の抽象文字を表すことがあります。― 例えば、"ñ" の文字は以下のいずれかで表すことができます。※ U+300~036F:ダイアクリティカルマーク(合成可能)
let string1='\u00F1'; D=string1; //="ñ" let string2='\u006E\u0303'; D=string2; //="ñ"
しかし、コード ポイントが異なるため、文字列の比較ではこれらが同じものとして扱われません。また、それぞれのコード ポイントの数が異なるため、長さすら異なります。
let string1='\u00F1'; //="ñ" let string2='\u006E\u0303'; //="ñ" D=string1 === string2; //=false D=string1.length; //=1 D=string2.length; //=2
normalize() メソッドは、同じ文字を表すコード ポイントのすべての並びを共通の正規化された形式に文字列を変換することで、この問題を解決するのに役立ちます。正規化の方法は主に二つがあり、一つは正準等価性に、もう一つは互換等価性に基づきます。
Unicode では、二つのコード ポイントの並びが同じ抽象文字を表していれば、正準等価性があるとされ、常に同じ外見表示と動作をするべきです(例えば、並べ替えで常に同じものとして扱うべきです)。
normalize() を "NFD" または "NFC" の引数で使用することで、すべてが正準等価な文字列となる文字列の形を生成することができます。
以下の例では、文字 "ñ" の二つの表現を正規化しています:
let string1 = '\u00F1'; // ñ let string2 = '\u006E\u0303'; // ñ string1 = string1.normalize('NFD'); string2 = string2.normalize('NFD'); D=string1 === string2; //=true D=string1.length; //=2 D=string2.length; //=2
"NFD" で正規化された形の長さが 2 であることに注意してください。"NFD" は分解正規形を生成するからであり、これは単一のコード ポイントを複数のコード ポイントの組み合わせに分解します。"ñ" の分解正規形は "\u006E\u0303" です。
"NFC" を指定すると合成正規形を取得することができ、これは複数のコード ポイントを可能な限り単一のコード ポイントで置き換えます。"ñ" の合成正規形は "\u00F1" です。
let string1 = '\u00F1'; //="ñ" let string2 = '\u006E\u0303'; //="ñ" string1 = string1.normalize('NFC'); string2 = string2.normalize('NFC'); D=string1 === string2; //=true D=string1.length; //=1 D=string2.length; //=1 D=string2.codePointAt(0).toString(16)); //=f1。(16進表記に変換)
Unicode では、二つのコード ポイントの並びが、同じ抽象文字を表す場合に互換性があり、場合によっては同じ文字として扱われるべきですが、すべてのアプリケーションでそうするべきとは限らないことがあります。
すべての正準等価な並びは互換といえますが、逆はそうとはいえません。
例を挙げます。
場面によっては(並べ替えなど)同じものとしてみなされるべきであり、その他の場合は(外見など)同じとするべきではないので、これらは厳密には等しくありません。
normalize() を "NFKD" または "NFKC" を引数にして使用することで、互換等価な文字列が同じになる形の文字列を生成することができます。
let string1 = '\uFB00'; let string2 = '\u0066\u0066'; D=string1; //="ff" D=string2; //="ff" D=string1 === string2; //=false D=string1.length; //=1 D=string2.length; //=2 string1 = string1.normalize('NFKD'); string2 = string2.normalize('NFKD'); D=string1; //="ff"。外見が変わった D=string2; //="ff" D=string1 === string2; //=true D=string1.length; //=2 D=string2.length; //=2
互換等価な正規化を適用する際には、正規化された形式がすべてのアプリケーションに適しているとは限らないので、文字列で何をしようとしているのかを考慮することが重要です。上の例では、ユーザーが "f" を検索すれば文字列を見つけることができるので、正規化は検索に適しています。しかし、視覚的な表現が異なるため、表示には適切ではないかもしれません。
正準等価な正規化のように、分解形または合成形の互換等価形式は、それぞれ "NFKD" または "NFKC" を渡すことで問い合わせることができます。
// 最初の文字列 // U+1E9B: LATIN SMALL LETTER LONG S WITH DOT ABOVE // U+0323: COMBINING DOT BELOW let str='\u1E9B\u0323'; //="ẛ̣" // Canonically-composed form (NFC) // U+1E9B: LATIN SMALL LETTER LONG S WITH DOT ABOVE // U+0323: COMBINING DOT BELOW D=str.normalize('NFC'); //="ẛ̣" D=str.normalize(); //=同上 // Canonically-decomposed form (NFD) // U+017F: LATIN SMALL LETTER LONG S // U+0323: COMBINING DOT BELOW // U+0307: COMBINING DOT ABOVE D=str.normalize('NFD'); //="ẛ̣"。("\u017F\u0323\u0307") // Compatibly-composed (NFKC) // U+1E69: LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE D=str.normalize('NFKC'); //="ṩ"。("\u1E69") // Compatibly-decomposed (NFKD) // U+0073: LATIN SMALL LETTER S // U+0323: COMBINING DOT BELOW // U+0307: COMBINING DOT ABOVE D=str.normalize('NFKD'); //="ṩ"。("\u0073\u0323\u0307")