まくまくJavaScriptノート
全角文字と半角文字を含んだ文字列を正規化して表記ゆれを吸収する (normalize)
2019-04-08
ECMAScript2015 で定義された String#normalize() は、Unicode 正規化を行うためのメソッドです。これを利用すると、文字列中の全角文字を半角文字に変換することができます。

String.prototype.normalize() - JavaScript|MDN

String#normalize() のパラメータとして、NFKC(正規化形式 KC)を指定して文字列を正規化すると、ある文字列中に含まれる半角文字や全角文字を正規化して表現を統一することができます。 これを利用すると、テキスト検索などのプログラムにおける表記ゆれの問題を(ある程度)解決できます。

下記のサンプルコードでは、半角カタカナ(アイウエオ)と、全角アルファベット(ABC)を normalize() を使って正規化しています。

const s1 = 'アイウエオ';
const s2 = 'ABC';
console.log(`${s1} => ${s1.normalize('NFKC')}`);
console.log(`${s2} => ${s2.normalize('NFKC')}`);

実行結果

アイウエオ => アイウエオ
ABC => ABC

半角カタカナは全角に、全角アルファベットは半角に変換されていることがわかります。

いろいろな正規化フォーマット

String#normalize() では、下記のような Unicode 正規化フォーマットを指定できるようになっています。

  • 'NFC' … Normalize Format C: 正規化形式 C (デフォルト)
  • 'NFD' … Normalize Format D: 正規化形式 D
  • 'NFKC' … Normalize Format KC: 正規化形式 KC
  • 'NFKD' … Normalize Format KD: 正規化形式 KD

正規化フォーマットの詳細仕様に関しては下記を参照してください。

下記のようなサンプルコードで、それぞれの正規化フォーマットによる変換を試すことができます。

const TEXTS = [
  'アイウエオ',
  'パピプペポ',
  'パピプペポ',
  'abcABC',
  '123',
  '+-.~)}',
];
const FORMS = ['NFC', 'NFD', 'NFKC', 'NFKD'];

TEXTS.forEach(function(t) {
  FORMS.forEach(function(f) {
    console.log(`${t} ==(${f})==> ${t.normalize(f)}`);
  });
});

実行結果

アイウエオ ==(NFC)==> アイウエオ
アイウエオ ==(NFD)==> アイウエオ
アイウエオ ==(NFKC)==> アイウエオ
アイウエオ ==(NFKD)==> アイウエオ
パピプペポ ==(NFC)==> パピプペポ
パピプペポ ==(NFD)==> パピプペポ
パピプペポ ==(NFKC)==> パピプペポ
パピプペポ ==(NFKD)==> パピプペポ
パピプペポ ==(NFC)==> パピプペポ
パピプペポ ==(NFD)==> パピプペポ
パピプペポ ==(NFKC)==> パピプペポ
パピプペポ ==(NFKD)==> パピプペポ
abcABC ==(NFC)==> abcABC
abcABC ==(NFD)==> abcABC
abcABC ==(NFKC)==> abcABC
abcABC ==(NFKD)==> abcABC
123 ==(NFC)==> 123
123 ==(NFD)==> 123
123 ==(NFKC)==> 123
123 ==(NFKD)==> 123
+-.~)} ==(NFC)==> +-.~)}
+-.~)} ==(NFD)==> +-.~)}
+-.~)} ==(NFKC)==> +-.~)}
+-.~)} ==(NFKD)==> +-.~)}

参考

Java にも同様の Unicode 正規化を行うためのクラス java.text.Normalizer が用意されています。

2019-04-08