K_DM Book
用語集
対象者 標準
対象者別の入口 →

対象者の設定はこのブラウザの中にだけ保存されます。

言語 JA

漢数字をアラビア数字へ変換する

01.7.4

漢数字をアラビア数字へ変換する

最終更新 2020-03-11 読了時間 3 分
まとめ
「三千五百二十円」「12億3000万」「約五万二千」のような漢数字入りの文字列を 3520、1230000000、52000 の整数に変換します。漢数字は「十・百・千」の小単位と「万・億・兆」の大単位で位取りが決まるので、1 文字ずつ読みながら number(直前の数字)、section(万未満の作業領域)、total(確定した大きな桁)の 3 つの変数に足し込んでいきます。全角の「12」や混在する「4兆5000億」も isdigit で同じように扱えます。「二〇二三」のような位取りなしの表記には対応しないので、その限界も確認します。

直感 #

帳票やアンケートでは「三千五百二十円」や「約2億円」のように漢数字が混在し、そのままでは astype(int) も平均の計算もできません。「三千五百二十」は 3 × 1000 + 5 × 100 + 2 × 10 です。「十・百・千」は直前の数字に掛ける小さな単位で、「万・億・兆」はそれまでに作った 4 桁までの数(セクション)を丸ごと持ち上げる大きな単位なので、「十二億三千万」は (12) × 1 億 + (3000) × 1 万 と読みます。この「数字を覚える → 小単位で掛けてセクションに足す → 大単位でセクションを総計に繰り上げる」の 3 動作を 1 文字ずつ繰り返すのが、下の関数の全てです。

Python で変換する #

次のコードは数字・小単位・大単位の 3 つの辞書を持ち、kanji_to_int が文字列を 1 文字ずつ読んで整数を返します。サンプルは 4 パターンです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
KANJI_DIGITS = {
    "零": 0, "〇": 0,
    "一": 1, "二": 2, "三": 3, "四": 4, "五": 5,
    "六": 6, "七": 7, "八": 8, "九": 9,
}
KANJI_UNITS = {"十": 10, "百": 100, "千": 1000}
KANJI_BIG_UNITS = {"万": 10_000, "億": 100_000_000, "兆": 1_000_000_000_000}

def kanji_to_int(text: str) -> int:
    text = text.replace("約", "").replace("およそ", "")
    total = 0
    section = 0
    number = 0

    for ch in text:
        if ch in KANJI_DIGITS:
            number = KANJI_DIGITS[ch]
        elif ch in KANJI_UNITS:
            unit = KANJI_UNITS[ch]
            section += max(number, 1) * unit
            number = 0
        elif ch in KANJI_BIG_UNITS:
            unit = KANJI_BIG_UNITS[ch]
            section += number
            total += max(section, 1) * unit
            section = 0
            number = 0
        elif ch.isdigit():
            number = number * 10 + int(ch)
        else:
            continue

    return total + section + number

samples = ["三千五百二十円", "12億3000万", "4兆5000億", "約五万二千"]
for s in samples:
    print(s, "→", kanji_to_int(s))

実行結果の読み方 #

「三千五百二十円」は section に 3000 + 500 + 20 が積まれ、「円」を飛ばして 3520 が返ります。「12億3000万」は 1230000000 です。「約五万二千」は「約」が消えて 5 × 1 万 + 2 × 1000 = 52000 になり、「4兆5000億」も半角数字が isdigit で読まれて 4500000000000 になります。注意したいのは「二〇二三」のような位取りを使わない表記で、数字が連続すると number が上書きされるため結果は 3 になります。年号や電話番号のような並べ書きの漢数字は、KANJI_DIGITS で 1 文字ずつアラビア数字に置換する別の関数で処理してください。

使いどころと落とし穴 #

「兆」より大きい「京」「垓」が出る業種では、KANJI_BIG_UNITS に "京": 10_000_000_000_000_000 のように追記すれば同じループで動きます。「数十」「数百」といった曖昧表現は「数」が読み飛ばされて 10 や 100 になるので、0〜9 の仮の値で置き換えるか、曖昧であることを示すフラグ列を別に持つ運用が安全です。カンマ付きのアラビア数字(「1,234」)はカンマが読み飛ばされて 1234 になりますが、小数点の「1.5万」は「.」が落ちて 15 × 1 万になるため、小数を含む列では正規表現でアラビア数字部分を先に float に直してから漢数字の単位だけを掛けるほうが安全です。