手軽屋
ツール一覧

Unicode正規化NFCとは何か|濁点が検索でヒットしない理由

「見た目は同じなのに検索でヒットしない」現象は、Unicode正規化のばらつきが原因です。

参照した一次情報

なぜ「が」が2種類あるのか

Unicodeでは「が」を表現する方法が2つあります。

画面上はどちらも「が」と見えますが、内部のバイト列は全く別物。「が」(合成済み)を検索しても「が」(結合)はヒットしません。これが「コピペしたら検索が効かない」現象の正体です。

4つの正規化形式

Unicode UAX#15は4つの正規化形式を定義しています。MDN String.prototype.normalize()の引数として指定可能です。

形式正式名称特徴
NFCNormalization Form Canonical Composition合成済みに統一(推奨・本ツール採用)
NFDNormalization Form Canonical Decomposition結合文字列に分解(macOSファイル名)
NFKCCompatibility Composition互換等価まで統一(半角→全角統一など)
NFKDCompatibility Decomposition互換等価を分解してから結合形式へ

JavaScriptでの動作例

// MDN公式例
const composed = "\u304C";              // が(合成済み 1文字)
const decomposed = "\u304B\u3099";      // か + 濁点(2文字)

console.log(composed === decomposed);     // false
console.log(composed.length);             // 1
console.log(decomposed.length);           // 2

// NFCで両者を統一すると一致
console.log(
  composed.normalize("NFC") === decomposed.normalize("NFC")
); // true

MDNは「同じ表示の文字列でも、内部のコードポイント値が異なる場合がある」と明記。 正規化を行わずに比較すると「同じに見えるのに別の文字列」と判定されてしまいます。

現実によくあるトラブル

UAX#15の設計思想

Unicode® Standard Annex #15は2025-07-30公開のVersion 17.0.0で、エディタはKen Whistler氏。 このAnnexは「実装が文字列を正規化された形式で保持すれば、等価な文字列が一意のバイナリ表現を持つことが保証される」と明記。 つまり「見た目で等価なら、データとしても等価」を担保するためのルールです。

正規化形式には標準等価性(Canonical Equivalence)互換等価性(Compatibility Equivalence)の2軸があります。 標準等価性は「同じ文字を表す異なる符号化」(が=か+濁点)、 互換等価性は「視覚的に似た別文字」(半角ガ↔全角ガ、丸数字①↔(1))まで含みます。

NFCとNFKCの使い分け

一般的な文章整形ではNFCを使います。 見た目が同じ文字を統一しつつ、半角カタカナと全角カタカナは別物として残せるため、原文の意図を保てるからです。

一方、検索インデックス用・固有名詞の同一視判定など「見た目が似ていれば同じ扱い」を求める場面ではNFKCを使うと、半角ガ=全角ガ・①=1なども統一できます。ただし元の表記情報は失われます。

本ツールでの位置づけ

本ツールは「不可視文字除去+NFC正規化」処理で、MDN仕様に従いString.prototype.normalize('NFC')を適用しています。これにより、macOS由来のPDF・OCRで紛れ込む結合文字列を、合成済み形式に統一。 検索・置換・差分比較で「同じに見えるのにヒットしない」問題を解消します。

半角ガと全角ガを統一したい場合は、別ツール「全角半角変換」をあわせてご利用ください。

関連ツール・記事