一見簡単な要求ですが、ネット上で広く流通している[u4e00-u9fa5]
には実際に少し問題があります。
正規表現を使って漢字のすべての関連文字をマッチさせる方法#
ウィキペディアの Unicode ページの歴史セクションに示されているコード範囲からわかるように、中国のインターネットで広く流通している[u4e00-u9fa5]
は、実際には【CJK Unified Ideographs】内の漢字のみを計算しているはずですが、この部分の内容は実際にはすべての漢字の五分の一しか占めていません。CJK Unified Ideographs は使用頻度に基づいて区分されていますが、言語文字関連の専門ツールを開発する場合は、すべての関連文字を包括的にカバーするのが最善です。
範囲 | 名称 | 字数 |
---|---|---|
U+4E00 - U+9FFF | CJK Unified Ideographs | 20,992 |
U+3400 - U+4DBF | CJK Unified Ideographs Extension A | 6,592 |
U+20000 - U+2A6DF | CJK Unified Ideographs Extension B | 42,720 |
U+2A700 - U+2B738 | CJK Unified Ideographs Extension C | 4,154 |
U+2B740 - U+2B81D | CJK Unified Ideographs Extension D | 222 |
U+2B820 - U+2CEA1 | CJK Unified Ideographs Extension E | 5,762 |
U+2CEB0 - U+2EBE0 | CJK Unified Ideographs Extension F | 7,473 |
U+30000 - U+3134A | CJK Unified Ideographs Extension G | 4,939 |
U+31350 - U+323AF | CJK Unified Ideographs Extension H | 4,192 |
U+2EBF0 - U+2EE5F | CJK Unified Ideographs Extension I | 622 |
合計 | 97,668 |
UniCode に関連する問題に直面した場合、最良の方法は Unicode 公式が提供している文書Unicode 15.1 Character Code Chartsを参照することです。この文書には、上記の【CJK Unified Ideographs】の他にも、漢字に関連する記号(部首、注音符号、拼音)、私有区などが言及されています。
以下に Python 実装の例を示します:
"""漢字関連文字をマッチさせる"""
import re
# noinspection RegExpDuplicateCharacterInClass
ideographs_reg = re.compile(
r"""(?P<cjk_unified_ideographs>[\u4E00-\u9FFF])|
(?P<extension_a>[\u3400-\u4DBF])|
(?P<extension_b>[\u20000-\u2A6DF])|
(?P<extension_c>[\u2A700-\u2B738])|
(?P<extension_d>[\u2B740-\u2B81D])|
(?P<extension_e>[\u2B820-\u2CEA1])|
(?P<extension_f>[\u2CEB0-\u2EBE0])|
(?P<extension_g>[\u30000-\u23134A])|
(?P<extension_h>[\u31350-\u323AF])|
(?P<extension_i>[\u2EBF0-\u2EE5F])|
(?P<compatibility_ideographs>[\uF900-\uFAFF])| # 互換区:([\x{F900}-\x{FAD9}])
(?P<compatibility_ideographs_supplement>[\u2F800-\u2FA1F])| # 互換拡張区:([\x{2F800}-\x{2FA1D}])
(?P<kangxi_radicals>[\u2F00-\u2FDF]) | # 康熙部首:([\x{2F00}-\x{2FD5}])
(?P<radicals_supplement>[\u2E80-\u2EFF]) | # 部首拡張:([\u2E80-\u2EF3])
(?P<cjk_strokes>[\u31c0-\u31ef]) | # 漢字筆画:([\u31C0-\u31E3])
(?P<ideographic_description_characters>[\u2FF0-\u2FFF]) #漢字構造:([\u2FF0-\u2FFB])
(?P<bopomofo>[\u3100-\u312F])| # 漢語注音:([\u3105-\u312F])
(?P<bopomofo_extend>[\u31A0-\u31BF])| # 注音拡張:([\u31A0-\u31BA])
(?P<private_use_area>[\uE000-\uF8FF])| # 私有区:([\uE000-\uF8FF])
(?P<supplementary_private_use_area_a>[\uF0000-\uFFFFF])| # 私用PUA-A:([\uF0000-\uFFFFF])
(?P<supplementary_private_use_area_b>[\u100000-\u10FFFD])| # 私用PUA-B:([\u100000-\u10FFFF])
"""
)
def match_chinese_ideographs(input_text: str) -> bool:
"""漢字関連文字を含むかどうかをマッチさせる
Args:
input_text (str): マッチさせる文字列
Returns:
漢字関連の文字を含む場合はTrueを返す
"""
result = False
for char in input_text:
if re.search(ideographs_reg, char) is not None:
print(re.match(ideographs_reg, char).groupdict())
result = True
return result
match_chinese_ideographs("食物")
補足#
感謝 amob の提案:
あなたのブログでの漢字の正規表現マッチに関する記事を見ましたが、私自身も少し経験があります(珍しい漢字が多い辞書を扱ったことがあります)。現在 \p {han} はまだ Unicode 13.0 に基づいており、多くの新しい漢字をマッチさせることができません。\p {Unified_Ideograph}/u は使ったことがなく、特殊なケースをマッチできないと思います。
サイト内の高名な jcz777 の指導により、現在最も理想的なマッチコードポイントは以下の通りです:
基本区:([\x{3007}\x{4e00}-\x{9fff}])
A区:([\x{3400}-\x{4DBF}])
B区:([\x{20000}-\x{2A6DF}])
C区:([\x{2A700}-\x{2B73F}])
D区:([\x{2B740}-\x{2B81F}])
E区:([\x{2B820}-\x{2CEA1}])
F区:([\x{2CEB0}-\x{2EBE0}])
G区:([\x{30000}-\x{3134A}])
H区:([\x{31350}-\x{323AF}])
I区:([\x{2EBF0}-\x{2EE5F}])
互換区:([\x{F900}-\x{FAD9}])
互換拡張区:([\x{2F800}-\x{2FA1D}])
康熙部首:([\x{2F00}-\x{2FD5}])
漢字筆画:([\x{31C0}-\x{31E3}])
漢字構造:([\x{2FF0}-\x{2FFB}])
漢語注音:([\x{3105}-\x{312F}])
注音拡張:([\x{31A0}-\x{31BA}])
部首拡張:([\x{2E80}-\x{2EF3}])
私有区:([\x{E000}-\x{F8FF}])
私用PUA-A:([\x{F0000}-\x{FFFFF}])
私用PUA-B:([\x{100000}-\x{10FFFF}])
これらを考慮に入れると、
𝍦、𝍳、𝍳、𝍴、𝍵
〡、〢、〣、〤、〥、〦、〧、〨、〩、〸
参考#
JavaScript 正規表現で漢字をマッチさせる:[[Python]] にはこの文書で言及されている/\p{Unified_Ideograph}/u
や/\p{Script=Han}/u
に類似した方法がないため、第三者ライブラリの価値があると思います(困惑
Python:複雑な正規表現を構築する方法:実際の開発シーンで、修正やデバッグが容易な正規表現の使い方を紹介しています。