あらすじ
ある文字列が日本語かそうでないか判別する必要があって、日本語でも使われる漢字なのか、日本語では使われない漢字なのか、超ざっくり判別するスクリプトを作りました。
原理
原理は、Unicodeのサイトに行って
Unihan.zipというファイルを取ってくると、中にUnihan_IRGSources.txtというタブ区切りテキストのファイルがあります。
こんな感じ。
U+3400 kIRG_GSource GKX-0078.01
U+3400 kIRG_JSource JA-2121
U+3400 kIRG_TSource T6-222C
U+3400 kRSUnicode 1.4
U+3400 kTotalStrokes 5
...
U+3400という字について調べると、kIRG_JSourceとしてJA-2121という値がマップされている。
kIRG_JSourceは日本語の典拠となった原規格と、その中でのコードポイントのことみたいです。
この字はJAの2121番。
JAというのはUnified Japanese IT Vendors Contemporary Ideographs, 1993という規格らしい。
https://www.unicode.org/reports/tr38/index.html#kIRG_JSource
Unified Japanese IT Vendors Contemporary Ideographsで検索すると、小形克宏さんの下の記事(2000年)に当たった。
https://internet.watch.impress.co.jp/www/column/ogata/part2_3.htm
この文字集合の典拠について詳細な説明は今にいたるまでなされていず、正体不明と言わざるをえない。
へぇー。。
で、U+3400という字は、㐀っていう微妙な字だった。
自分で書いたことも読んだこともないが、おかと読み、土を小さく盛ったお墓のことだそうだ。
いきなり悲しいわ!!!
https://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=3400
https://kanji.jitenon.jp/kanjin/6593.html
その下、U+3401について調べると、kIRG_JSourceがない。
だから、日本語では使わないと考えていいだろう!
という方針。
U+3401 kIRG_GSource G5-3024
U+3401 kIRG_KSource K3-2121
U+3401 kIRG_TSource T4-2224
U+3401 kRSUnicode 1.5
U+3401 kTotalStrokes 6
...
ちなみにU+3401は㐁という字。
テンと読んでむしろという意味だそうだ。
丙(ひのえ)と似てるね。。
なんか変な扉を開けたかもしれない。。
https://kanji.jitenon.jp/kanjin/6599.html
使い方
プログラムだが、自分用にPerlで書けば5分で書けるのに、Pythonな人とシェアする必要でPythonで書いた。
いつまで立っても馴染めんわPython...。
使い方は以下の通り。
スクリプトと同じところにUnihan_IRGSources.txtを置く必要がある。
$ python3 ./kanjiTest.py 㐀
㐀(code point=U+3400) is Japanese
$ python3 ./kanjiTest.py 㐁
㐁(code point=U+3401) is not Japanese
あはは動いてるわ。
中身
中身はこんな感じ。
# /usr/bin/python3
# kanjiTest.py
import sys
import csv
args = sys.argv
code_point = 'U+' + hex(ord(args[1]))[2:].upper()
tsv_file = 'Unihan_IRGSources.txt'
with open(tsv_file, 'r', encoding='utf-8', newline='') as f:
reader = csv.reader(f, delimiter='\t')
for row in reader:
jp_src = 0
if len(row) >= 1:
if row[0] == code_point and row[1] == 'kIRG_JSource':
jp_src = 1
print (args[1] + '(code point=' + code_point + ') is Japanese')
exit()
if jp_src == 0:
print (args[1] + '(code point=' + code_point + ') is not Japanese')
UTF-8な端末で、漢字1文字を引数で受け取って、ordでコードポイント化し、hexで16進にし、最初の0xを切り取り、upperで大文字化し、U+をくっつけている。
csvモジュールでdelimiter='\t'を指定するとTSVが読み込める。
各行はリストオブジェクトになり、1列目がUnicodeコードポイント(U+xxxx)に、2列目が典拠とする原規格の種類になるので、2列目がkIRG_JSourceとなる行があったら日本語だねと言って終了する。
最後まで行き着いたら、日本語じゃないねと言って終了する。
len(row)が1以上ですかと聞いているのは、最後の1回が空リストだかヌルだかが返るから。
これを入れないと最後の1行を読み込んだ後でIndex Out of the Rangeになる。
このプログラムがお行儀的にどうか知らないけど動いているようだ。
後記
と、ここまで書いて思ったけど、日本人が大好きな𠮷野家のヨシ(ツチヨシ、土+口型、U+20BB7)は、台湾由来でUnicodeで使えるけど、日本の規格では絶対に吉(サムライヨシ、士+口型、U+5409)と包摂されるので、kIRG_JSourceがないのである。
だから非日本語を返す。
$ python3 ./kanjiTest.py 𠮷
𠮷(code point=U+20BB7) is not Japanese
うーん。
どうなんだろうね。
(何この終わり方。。)
(この項終わり)