漢字にマッチする JavaScript の正規表現パターン ― 2015年12月31日 23時03分
たまに漢字にマッチする正規表現パターンを書きたいときがあります。Perl の正規表現だと Unicode のスクリプト名を使って \p{Han} で漢字にマッチさせられるのですが、JavaScript ではそうはいきません。JavaScript の正規表現には以下のふたつの問題があります。
- Unicode スクリプト名の指定 (
\p{...}) に対応していない。 - そもそも Unicode の符号位置に対してマッチさせられない (UTF-16 における符号単位に対するマッチになる)。
- BMP 外の文字にマッチさせたいときは、サロゲートペアの符号単位を記述する必要がある。
- これに関しては ECMAScript 2015 で導入された
/uフラグで解決する見込み。
とはいえ、解決不能な問題というわけでもないので、Perl の \p{Han} を JavaScript に移植してみましょう。\p{Han} の範囲は以下のコマンドで参照できます。
perl -MUnicode::UCD -MData::Dumper -E 'say Dumper Unicode::UCD::charscript("Han");'
Perl 5.20.2 (Unicode 6.3.0) では以下の範囲が含まれるとわかりました。
U+2E80-U+2E99U+2E9B-U+2EF3U+2F00-U+2FD5U+3005-U+3005U+3007-U+3007U+3021-U+3029U+3038-U+303BU+3400-U+4DB5U+4E00-U+9FCCU+F900-U+FA6DU+FA70-U+FAD9U+20000-U+2A6D6(\uD840\uDC00-\uD869\uDED6)U+2A700-U+2B734(\uD869\uDF00-\uD86D\uDF34)U+2B740-U+2B81D(\uD86D\uDF40-\uD86E\uDC1D)U+2F800-U+2FA1D(\uD87E\uDC00-\uD87E\uDE1D)
サロゲートペアが [\uD800-\uDBFF][\uDC00-\uDFFF] であることを踏まえると、BMP 外の範囲はそれぞれ以下の部分的な範囲に展開できます。
\uD840\uDC00-\uD869\uDED6[\uD840-\uD868][\uDC00-\uDFFF]\uD869[\uDC00-\uDED6]
\uD869\uDF00-\uD86D\uDF34\uD869[\uDF00-\uDFFF][\uD86A-\uD86C][\uDC00-\uDFFF]\uD86D[\uDC00-\uDF34]
\uD86D\uDF40-\uD86E\uDC1D\uD86D[\uDF40-\uDFFF]\uD86E[\uDC00-\uDC1D]
\uD87E\uDC00-\uD87E\uDE1D\uD87E[\uDC00-\uDE1D]
これらを整理して組み合わせると、最終的に以下のパターンが得られます。
/(?:[\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u3005\u3007\u3021-\u3029\u3038-\u303B\u3400-\u4DB5\u4E00-\u9FCC\uF900-\uFA6D\uFA70-\uFAD9]|[\uD840-\uD868][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|[\uD86A-\uD86C][\uDC00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D])/
というわけで「漢字 1 文字にマッチする JavaScript の正規表現パターン」でした。よいお年を。
最近のコメント