博客 / 詳情

返回

[開發技巧] 如何獲取漢字筆畫數?

[開發技巧] 如何獲取漢字筆畫數?

背景

在開發一個簡單的卜筮小腳本的過程中,遇見了這個有趣的問題。如果只是特定個別漢字,我們大可以硬編碼一個字典在腳本中,但是如果想獲取任意一個漢字的筆畫數呢?

pypinyin庫

from pypinyin import pinyin, Style

def get_strokes_count(chinese_character):
    pinyin_list = pinyin(chinese_character, style=Style.NORMAL)
    strokes_count = len(pinyin_list[0])
    return strokes_count

character = input("請輸入一個漢字:")
strokes = get_strokes_count(character)
print("漢字'{}'的筆畫數為:{}".format(character, strokes))

嘗試了一下,發現得到的結果實際上是該漢字在normal拼音格式下的結果數,

pypinin wrong

unihan數據庫

unihan數據庫是一個由Unicode聯盟維護的漢字數據庫,看起來很靠譜,還提供了在線的工具。

在其在線查詢工具Unihan Database Lookup中進行檢索,發現查詢結果中
unihan_lokup
存在kTotalStrokes字段,即為所需的筆畫數數據。
作為unicode的官方數據庫,目前版本完全滿足基本的漢字查詢。

Nice! 離成功更進了一步!

從Unihan數據庫中獲取筆畫信息

最開始打算直接通過lookup發送查詢請求,hmmm,太慢了,地址在國外。發現數據庫文件本身也不大,就直接下載下來了。

Unihan下載地址

打開壓縮包,有文件若干.

Unihan_files.png

通過lookup檢索得到的結果,我們要的kTotalStrokes字段在IRG Source中,取出該文件。
在regex101中測試正則,取出要的unicode部分和筆畫數部分,單獨存成文件, 以供查詢.

編碼

  • 提取筆畫信息
file = Path("Stroke/Unihan_IRGSources.txt")
output = Path("Stroke/unicode2stroke.json")
stroke_dict = dict()
with open(file,mode="r") as f:
    for line in f:
        raw_line = line.strip()
        pattern = r"(U\+.*)\skTotalStrokes.*\s(\d+)"
        result = re.findall(pattern=pattern, string=raw_line)
        if len(result) == 0:
            continue
        unicode_key = result[0][0]
        unicode_stroke = result[0][1]
        print(f"{unicode_key}: {unicode_stroke}")
        stroke_dict[unicode_key] = unicode_stroke

with open(file=output, mode="w", encoding="utf-8") as f:
    json.dump(stroke_dict,f, ensure_ascii=False, indent=4)

導出成json文件方便訪問

  • 編寫獲取函數
with open(output) as f:
    unicode2stroke = json.load(f)

def get_character_stroke_count(char: str):
    unicode = "U+" + str(hex(ord(char)))[2:].upper()
    return int(unicode2stroke[unicode])

test_char = "阿"
get_character_stroke_count(char=test_char)

在獲取時,注意unicode將漢字轉為其對應的十六進制碼

成功!達到預期結果!

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.