2
1

More than 1 year has passed since last update.

ある漢字が日本語で使われているかどうかをざっくり判別する

Last updated at Posted at 2022-10-25

あらすじ

ある文字列が日本語かそうでないか判別する必要があって、日本語でも使われる漢字なのか、日本語では使われない漢字なのか、超ざっくり判別するスクリプトを作りました。

原理

原理は、Unicodeのサイトに行って

Unihan.zipというファイルを取ってくると、中にUnihan_IRGSources.txtというタブ区切りテキストのファイルがあります。
こんな感じ。

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

うーん。
どうなんだろうね。
(何この終わり方。。)

(この項終わり)

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1