2021年11月14日日曜日

漢字判定のいろいろな正規表現

漢字判定の正規表現は奥が深いです。 [一-龠] の記述がネット上にたくさんあるのですが、 「々ヵヶ」といった頻出語をサポートしてないことに気付きました。 みんな苦労しているみたい。 たまに必要になるので、自分なりの考えをメモしておきます。

結論はこちら。
[\u4E00-\u9FFF]        # CJK 統合漢字の基本多言語面
[\u4E00-\u9FFF𠮟]      # 常用漢字 (これもありかも)
[\u4E00-\u9FFF々]      # 実用上ここまではサポートしたい
[\u4E00-\u9FFF々ヵヶ]  # +頻出語
[\u4E00-\u9FFF々ヵヶヽヾゝゞ〃仝]  # +くり返し記号など
/[\u3400-\u9FFF\uF900-\uFAFF\u{20000}-\u{37FFF}]/u    # Unicode 15.1 漢字すべて
/[\u3400-\u9FFF\uF900-\uFAFF\u{20000}-\u{37FFF}々]/u  # Unicode 15.1 漢字すべて

漢字の指定

漢字の指定方法は、[一-龠] というものがネット上で多く見受けられ、私も利用していました。 最後の漢字が「龠」つまり U+9FA0 である理由は正直よくわからないのですが、たぶん Unicode 1.1 のときの指定を使っているのでしょう。 「龍」というよく使われる単語が、U+9F8D にあるので、それ以上の範囲削減は不可能です。 現在はさらに拡張されていますし、CJK 統合漢字の基本多言語面に基づく、[\u4E00-\u9FFF] が最も厳密な指定だろうと思います。

ちなみに [\u4E00-\u9FFF] の指定は JIS 第 2 水準までを想定した指定ですが、新常用漢字の「𠮟」を処理できないなどの問題があります。 ではどうするかというと、Unicode プロパティの /\p{scx=Han}/u を使う方法もあります。 ただこれでも「々」は判定できませんし、記号が含まれる致命的な問題があります。 同じことは /\p{scx=Hiragana}/u などにも言えて、Unicodeプロパティは意外と扱いに困ります。

ちょっと前に /[\u3400-\u9FFF\uF900-\uFAFF\u{20000}-\u{2FFFF}]/u という漢字判定もよく見かけました。 これもいい感じではあるのですが、今は CJK統合漢字拡張 H 以降に対応できていません。 そのため第3漢字面もサポートしないといけませんが、U+38000〜U+3AB9FF は甲骨文字がアサインされる予定があります。 甲骨文字も漢字と言えば漢字なのですが…漢字としてサポートするべきかは迷うところです。ひとまずサポートしないほうが良さそうかな。 そのギリギリ手前の U+37FFF までにするか、CJK統合漢字拡張 H の最終文字 U+323AF までにするかは難しいところです。 結局どこまでにするのが良いかは Unicode と CJK統合漢字の進化をよく見ながら決定するしかないのだろうと思います。

Unicode 15.1 (最新) の漢字すべてを想定した時に、現状でたぶん一番楽そうなのは、/[\u3400-\u9FFF\uF900-\uFAFF\u{20000}-\u{37FFF}]/u という漢字判定です。 Unicode フラグ u を付けた上で、\u{} で指定するのがポイント。

参考:

漢字に関連する語の指定

/\p{scx=Han}/u は使えそうで使い物にならないことが多いので、漢字や用例、文字コードに対する知識を深めるのは割と重要そうです。 くり返しを意味する「々」は漢字ではないらしいのですが、日常生活でも頻繁に出現します。 そのためたいていはサポートしないと、色々な不都合が生じます。

また「一ヶ所」のような使い方をする「ヵヶ」もたいてい必須語になります。 ただ「ヵヶ」は助数詞可能な名詞として出現し、必ず複合語として使われる漢字なので、サポートしなくていい場合もありそうです。 「ヵヶ」は Unicocde 的にはカタカナの一部として扱われているので、カタカナ語との重複に注意が必要です。 SudachiDict を見ると「ヶラヶラ」「スヵッ」「ヵッォ」などの謎エントリ以外はカタカナとして使っている用例が見当たりません。 単語としての単位ではカタカナからも除外したほうがよく、プログラミング的には漢字として扱って良いのではないかと思います。 余談ながら、カタカナの正規表現では、「ヵヶ」を除外しないでもいい時は [ァ-ヶ] と指定し、除外したい時は [ァ-ヴ] と指定するのが良さそうです。 /\p{scx=Hiragana}/u や /\p{scx=Katakana}/u はこのへんも扱いにくく、非常に使いにくい指定だったりします。 一番致命的なのは「ー」がひらがな/カタカナ判定されたり、記号が含まれるところですけどね。
くり返し記号は他にも「ヽヾゝゞ〃仝々」というものがあります。 先に述べた「々」もこの一部です。 現代語ではほぼ出現しませんが、「いすゞ」のような特殊例があります。 とはいえこちらは基本的には無視して大丈夫でしょう。 他にも「〆〇〻」といった漢字も、稀に出現はします。 ただ指定も面倒臭いので、これらは無視しても大丈夫でしょう。 ほとんどのケースでは、[\u4E00-\u9FFF々]、真面目にやるなら /[\u3400-\u9FFF\uF900-\uFAFF\u{20000}-\u{37FFF}々]/u で大丈夫じゃないでしょうか。
利用用途に応じて範囲を調整しないといけないのが地味に面倒です。

0 件のコメント: