← ハシトシステム トップ English ツール ブログ
入力
結果
0
UTF-16 コード単位
0
文字数(コードポイント)
0
UTF-8 バイト数
判定
結果UTF-16UTF-8入力との比較コードポイント

同じ「が」が2種類あるという話

ひらがなの「が」には2つの書き方があります。1文字の U+304C と、「か」U+304B に濁点 U+3099 を足した2文字です。画面上はどちらも同じに見えますが、文字列としては別物なので、単純な比較や検索では一致しません。macOS でファイル名に濁点を含めるとファイル一覧の並びや検索が食い違うことがあるのは、この違いが原因です。

Unicode はこれを揃えるために正規化形を定めています。合成側に寄せるのが NFC、分解側に寄せるのが NFD です。ウェブや多くのプロトコルは NFC を前提にしているので、外部から受け取った文字列は保存や比較の前に NFC へ正規化しておくのが実務上の既定です。

NFKC と NFKD は別の目的

K が付く形は互換分解を伴います。全角の「A」を半角の「A」に、半角カナの「ガ」を全角の「ガ」に、丸囲みの「㈱」を「(株)」に変えるといった、見た目の違いを潰す変換です。検索キーの正規化には便利ですが、元の表記には戻せません。表示用の文字列にそのまま適用すると、意図した見た目が失われます。

つまり、NFC は「同じ文字を同じ表現に揃える」ためのもの、NFKC は「違う文字を同じ扱いにする」ためのものです。役割が違うので、保存する値には NFC、検索インデックスには NFKC、というように使い分けます。

入力NFCNFDNFKC
が(合成済み)が(1文字)か + 濁点(2文字)が(1文字)
ガ(半角カナ)ガ(2文字のまま)ガ(2文字のまま)ガ(1文字)
A(全角)A(半角)
(株)

正規化はブラウザ標準の String.prototype.normalize で行っています。入力した文字列がサーバーへ送られることはありません。

よくある質問(FAQ)

同じ「が」なのに検索で一致しないのはなぜですか?

1文字の U+304C と、「か」U+304B に濁点 U+3099 を足した2文字という2通りの書き方があるためです。見た目は同じでも文字列としては別物なので、単純比較では一致しません。両方を NFC に正規化すれば揃います。

NFC と NFKC はどちらを使えばよいですか?

保存する値や表示する文字列には NFC を使います。NFKC は全角と半角や丸囲み文字を潰すので、検索インデックスの正規化には向きますが、元の表記に戻せません。用途で使い分けてください。

NFKC は元に戻せますか?

戻せません。互換分解は情報を捨てる変換で、たとえば「㈱」を「(株)」にした後にどちらが元だったかは分かりません。可逆にしたい場合は元の文字列も別に保存してください。

入力した文字列は送信されますか?

いいえ。正規化はブラウザ標準の String.prototype.normalize で行っており、入力内容がサーバーへ送信されることはありません。