シルギア

Unicode正規化ガイド|NFC/NFD/NFKC/NFKDの違いと使い分け

公開日:2026年9月17日 更新日:2026年9月15日 運営:シルギア(Analyzegear, Inc.) 対象ツール:Unicode正規化(NFC/NFD/NFKC/NFKD)

「が」という1文字は、内部で1つのデータで表される場合と、「か」と濁点の2つで表される場合があります。目には同じでも機械には別物で、そのまま比較すると一致しません。この“見た目は同じなのに中身が違う”を解消するのがUnicode正規化です。ここではNFC・NFD・NFKC・NFKDの4形式を、ツールで得られる数値とともに整理します。

Unicode正規化とは何か

Unicodeでは、同じ文字を複数のコードポイント列で表せることがあります。コードポイントとは「U+304C」のように文字に割り当てられた番号で、この並びが違えば画面上は同じでもデータとしては別物です。正規化は、こうした複数の表し方を決められた規則で1つの形にそろえる処理です。

そろえ方には「合成するか、分解するか」と「正準等価でそろえるか、互換等価まで踏み込むか」という2つの軸があります。この2軸の組み合わせが、NFC・NFD・NFKC・NFKDという4つの形式です。正準等価とは、見た目も意味も完全に同じとみなせる関係のこと。互換等価とは、丸数字①と数字1のように「意味は近いが見た目が違う」関係まで含めた広いそろえ方です。頭の「K」は互換(compatibility)を表し、KがあるNFKC・NFKDだけが互換等価まで扱います。

4形式の全体像

4形式の役割は次のように整理できます。

  • NFC(正規合成):分解された結合文字を可能な限り合成した形。Webページやテキスト保存でもっとも一般的です。
  • NFD(正規分解):合成済みの文字を基底文字と結合文字に分けた形。macOSがファイル名の内部で使う形式です。
  • NFKC(互換合成):全角英数・①・㍿などの互換文字を通常の文字へ置き換えたうえで合成。検索の正規化に向きます。
  • NFKD(互換分解):互換文字を置き換えたうえで、さらに結合文字に分解した形です。

ポイントは、NFCとNFDは文字の見た目を変えないのに対し、NFKCとNFKDは「①→1」のように見た目そのものを別の文字へ変えてしまう点です。だからNFKC系は表示用ではなく、検索やキー照合の内部処理に使うのが基本です。

「が」で見る合成と分解

もっとも分かりやすい例が濁点付きの「が」です。入力「が」を本ツールに与えると、元テキストは1コードポイント(U+304C)・3バイトです。ここで各形式は次のようになります。

  • NFC:U+304C の1コードポイント・3バイト(元と同じ)
  • NFD:U+304B(か)+U+3099(結合用の濁点)の2コードポイント・6バイト(元と異なる)
  • NFKC・NFKD:それぞれNFC・NFDと同じ結果(1コードポイント/2コードポイント)になります

分解形のNFD・NFKDでは、1つだった「が」が「か」と濁点の2つに割れるため、コードポイント数が1から2へ、UTF-8バイト長も3から6へ増えます。これは正準等価の範囲での変化なので互換扱いのNFKCでも合成形は変わりません。同じ「が」でもどの形式で保存されたかでバイト長まで変わる、これが不一致の根本原因です。

互換文字はNFKC/NFKDでどう変わるか

互換文字は、丸数字や単位記号のように「1つの記号にまとめられた特殊な文字」です。NFC・NFDでは変化せず、NFKC・NFKDで初めて通常の文字列に展開されます。本ツールで確認できる代表例は次の通りです。

  • 丸数字「①②③」→ NFKCで「123」。3コードポイント・9バイトが、半角数字3文字・3バイトに縮みます。
  • ㍿(U+337F)→ NFKCで「株式会社」。1文字が漢字4文字(4コードポイント・12バイト)に展開されます。
  • 全角「A123」→ NFKCで「A123」。文字数は4のままですが、12バイトから4バイトへ減ります。
  • ローマ数字「Ⅷ」→ NFKCで「VIII」。1文字がV・I・I・Iの4文字になります。
  • 合字「fi」→ NFKCで「fi」の2文字。上付き「㎡」→ NFKCで「m2」。

半角カナも良い例です。「パ」(半角ハ+半角半濁点の2コードポイント)はNFKCでは全角「パ」1コードポイントに合成され、NFKDでは「ハ」+結合用半濁点の2コードポイントに分解されます。同じ互換等価でも合成のNFKCと分解のNFKDで結果が違うことが数値で分かります。㍿のように文字数が増える変換と、全角→半角のようにバイト長が減る変換の両方が起きるのが互換変換の特徴です。

検索・ファイル名・照合での実務活用

正規化が効くのは、テキストの「不一致」を防ぎたい場面です。検索では、入力欄の文字とデータ側の文字を同じ形式(多くはNFKC)にそろえてから照合すると、全角・半角や互換文字、濁点の合成・分解の違いをまとめて吸収でき、取りこぼしが減ります。

ファイル名の食い違いも典型です。macOSは内部でNFDに近い分解形、Windows/Linuxは合成形のNFCが多いため、濁点付きの名前などで「別ファイル扱い」「重複」「検索漏れ」が起き、どちらかの形式にそろえると解消しやすくなります。パスワードやIDの照合でも、入力方法で濁点が合成・分解のどちらで入るかが変わり、「正しいはずなのに通らない」原因になります。ただしNFKCは㍿→株式会社のように意味が変わって見える変換も含むため表示に残す文字列には向かず、用途によっては合成だけそろえるNFCが無難な場合もあります。

使い方と注意点

使い方はシンプルです。「正規化するテキスト」の欄に確認したい文字を入力すると、入力と同時に4形式の結果カードが並びます。各カードにはコードポイント数・UTF-8バイト長・「元と同じ/元と異なる」の判定が出て、「コードポイント内訳(U+xxxx)も表示する」にチェックを入れれば、どのコードポイントに分解・合成されたかまで追えます。

注意点として、コードポイント数はサロゲートペアの絵文字も1文字と数えますが、JavaScriptの文字列lengthは16ビット単位で絵文字を2と数えるため、両者は一致しないことがあります。また、肌色や国旗などのZWJシーケンス・異体字セレクタを含む結合絵文字は、正規化しても複数コードポイントのまま保持されます。処理はすべてブラウザ内のString.prototype.normalize()で行われ、入力内容は送信されずオフラインでも使えます。まず「が」や①、㍿を入れ、4形式で数値がどう動くかを目で確かめるのが理解への近道です。

「Unicode正規化(NFC/NFD/NFKC/NFKD)」を使ってみる →

ほかの記事

HTML→Markdown変換の使い方|貼るだけで見出し・表・コードを安全に変換 絵文字→コードポイント変換の使い方|U+・サロゲート・ZWJの仕組み Base58/Base32/Base16変換の仕組みガイド|なぜ0OIlを除くのか cubic-bezierイージング入門|4つの数値と制御点の意味を図解 文字化けを直す仕組み|バイトに戻して再デコードする復元の考え方 ULIDとは何か|26文字で時系列ソートできるIDの仕組みと使い分け

記事一覧をすべて見る →