同じに見えるのに一致しない文字列を、NFC・NFD・NFKC・NFKD で並べて確かめます
| 形 | 結果 | UTF-16 | UTF-8 | 入力との比較 | コードポイント |
|---|
ひらがなの「が」には2つの書き方があります。1文字の U+304C と、「か」U+304B に濁点 U+3099 を足した2文字です。画面上はどちらも同じに見えますが、文字列としては別物なので、単純な比較や検索では一致しません。macOS でファイル名に濁点を含めるとファイル一覧の並びや検索が食い違うことがあるのは、この違いが原因です。
Unicode はこれを揃えるために正規化形を定めています。合成側に寄せるのが NFC、分解側に寄せるのが NFD です。ウェブや多くのプロトコルは NFC を前提にしているので、外部から受け取った文字列は保存や比較の前に NFC へ正規化しておくのが実務上の既定です。
K が付く形は互換分解を伴います。全角の「A」を半角の「A」に、半角カナの「ガ」を全角の「ガ」に、丸囲みの「㈱」を「(株)」に変えるといった、見た目の違いを潰す変換です。検索キーの正規化には便利ですが、元の表記には戻せません。表示用の文字列にそのまま適用すると、意図した見た目が失われます。
つまり、NFC は「同じ文字を同じ表現に揃える」ためのもの、NFKC は「違う文字を同じ扱いにする」ためのものです。役割が違うので、保存する値には NFC、検索インデックスには NFKC、というように使い分けます。
| 入力 | NFC | NFD | NFKC |
|---|---|---|---|
| が(合成済み) | が(1文字) | か + 濁点(2文字) | が(1文字) |
| ガ(半角カナ) | ガ(2文字のまま) | ガ(2文字のまま) | ガ(1文字) |
| A(全角) | A | A | A(半角) |
| ㈱ | ㈱ | ㈱ | (株) |
正規化はブラウザ標準の String.prototype.normalize で行っています。入力した文字列がサーバーへ送られることはありません。
1文字の U+304C と、「か」U+304B に濁点 U+3099 を足した2文字という2通りの書き方があるためです。見た目は同じでも文字列としては別物なので、単純比較では一致しません。両方を NFC に正規化すれば揃います。
保存する値や表示する文字列には NFC を使います。NFKC は全角と半角や丸囲み文字を潰すので、検索インデックスの正規化には向きますが、元の表記に戻せません。用途で使い分けてください。
戻せません。互換分解は情報を捨てる変換で、たとえば「㈱」を「(株)」にした後にどちらが元だったかは分かりません。可逆にしたい場合は元の文字列も別に保存してください。
いいえ。正規化はブラウザ標準の String.prototype.normalize で行っており、入力内容がサーバーへ送信されることはありません。