卿少納言

卿少納言

JavaScript & Japanese, Python & Polyglot, TypeScript & Translate.
zhihu
github
email
x

浅入深出日本語仮名変換

要約:知っていることを知るだけでなく、その理由を知ることが重要です。

平仮名変換#

結論#

カタカナから平仮名へ

def convert_kata_to_hira(input_text):
    process_texts = []
    for gana in input_text:
        if 12448 <= ord(gana) <= 12534:  # カタカナ文字に一致
            hira = chr(ord(gana) - 96)  # 平仮名に変換
            process_texts.append(hira)
    output_text = "".join(process_texts)
    return output_text

平仮名からカタカナへ

def convert_hira_to_kata(input_text):
    process_texts = []
    for gana in input_text:
        if 12353 <= ord(gana) <= 12438:  # 平仮名文字に一致
            hira = chr(ord(gana) + 96)  # カタカナに変換
            process_texts.append(hira)
    output_text = "".join(process_texts)
    return output_text

平仮名 Unicode#

Unicode 組織が提供する Unicode 標準ファイル U3040.pdf によると、平仮名の十進数範囲は 12353-12447、十六進数範囲は[\u3041-\u309f](正規表現の文字エスケープは十六進数を使用)。

文字十進数十六進数
123533041
123543042
123553043
123563044
123573045
123583046
123593047
123603048
123613049
12362304A
12363304B
12364304C
12365304D
12366304E
12367304F
123683050
123693051
123703052
123713053
123723054
123733055
123743056
123753057
123763058
123773059
12378305A
12379305B
12380305C
12381305D
12382305E
12383305F
123843060
123853061
123863062
123873063
123883064
123893065
123903066
123913067
123923068
123933069
12394306A
12395306B
12396306C
12397306D
12398306E
12399306F
124003070
124013071
124023072
124033073
124043074
124053075
124063076
124073077
124083078
124093079
12410307A
12411307B
12412307C
12413307D
12414307E
12415307F
124163080
124173081
124183082
124193083
124203084
124213085
124223086
124233087
124243088
124253089
12426308A
12427308B
12428308C
12429308D
12430308E
12431308F
124323090
124333091
124343092
124353093
124363094
124373095
124383096
124393097
124403098
124413099
12442309A
12443309B
12444309C
12445309D
12446309E
12447309F

カタカナ Unicode#

U30A0.pdf によると、十六進数の範囲は[\u30a0-\u30ff]、十進数範囲は 12448-12543。

文字十進数十六進数
1244830A0
1244930A1
1245030A2
1245130A3
1245230A4
1245330A5
1245430A6
1245530A7
1245630A8
1245730A9
1245830AA
1245930AB
1246030AC
1246130AD
1246230AE
1246330AF
1246430B0
1246530B1
1246630B2
1246730B3
1246830B4
1246930B5
1247030B6
1247130B7
1247230B8
1247330B9
1247430BA
1247530BB
1247630BC
1247730BD
1247830BE
1247930BF
1248030C0
1248130C1
1248230C2
1248330C3
1248430C4
1248530C5
1248630C6
1248730C7
1248830C8
1248930C9
1249030CA
1249130CB
1249230CC
1249330CD
1249430CE
1249530CF
1249630D0
1249730D1
1249830D2
1249930D3
1250030D4
1250130D5
1250230D6
1250330D7
1250430D8
1250530D9
1250630DA
1250730DB
1250830DC
1250930DD
1251030DE
1251130DF
1251230E0
1251330E1
1251430E2
1251530E3
1251630E4
1251730E5
1251830E6
1251930E7
1252030E8
1252130E9
1252230EA
1252330EB
1252430EC
1252530ED
1252630EE
1252730EF
1252830F0
1252930F1
1253030F2
1253130F3
1253230F4
1253330F5
1253430F6
1253530F7
1253630F8
1253730F9
1253830FA
1253930FB
1254030FC
1254130FD
1254230FE
1254330FF

カタカナ音声拡張 Unicode#

U31F0.pdf によると、十進数範囲:12784-12799、十六進数範囲は[\u31f0-\u31ff]

P.S. Unicode の公式説明によると、この部分の仮名は「アイヌ語」に使用されますが、私にはこの部分と上記の違いがわかりません 233

文字十進数十六進数
1278431F0
1278531F1
1278631F2
1278731F3
1278831F4
1278931F5
1279031F6
1279131F7
1279231F8
1279331F9
1279431FA
1279531FB
1279631FC
1279731FD
1279831FE
1279931FF

全半角仮名変換#

半角文字 Unicode#

UFF00.pdf によると、日本語の半角文字の範囲は 65381-65439、十六進数範囲:[\uff65-\uff9f]

文字十進数十六進数
65381FF65
65382FF66
65383FF67
65384FF68
65385FF69
65386FF6A
65387FF6B
65388FF6C
65389FF6D
65390FF6E
65391FF6F
65392FF70
65393FF71
65394FF72
65395FF73
65396FF74
65397FF75
65398FF76
65399FF77
65400FF78
65401FF79
65402FF7A
65403FF7B
65404FF7C
65405FF7D
65406FF7E
ソ65407FF7F
65408FF80
65409FF81
65410FF82
65411FF83
65412FF84
65413FF85
65414FF86
65415FF87
65416FF88
65417FF89
65418FF8A
65419FF8B
65420FF8C
65421FF8D
65422FF8E
65423FF8F
65424FF90
65425FF91
65426FF92
65427FF93
65428FF94
65429FF95
65430FF96
65431FF97
65432FF98
65433FF99
65434FF9A
65435FF9B
65436FF9C
65437FF9D
65438FF9E
65439FF9F

注:最初の文字は半角のです。

上記の表を観察すると、以下の 2 点に注意できます:

  1. 平仮名には半角仮名が存在しない(これはウィキペディアの半形仮名と一致します)
  2. 一部の平仮名の半角仮名は 2 つの文字で構成されているため、カタカナから平仮名への変換のようにhira = chr(int(ord(gana) - 96))で簡単に変換することはできず、文字列置換の方法を使用する必要があります。

したがって、全半角仮名の変換は平仮名からカタカナへの変換よりもはるかに面倒であり、個人的にはサードパーティのライブラリを使用することをお勧めします。

mojimoji#

全角から半角に変換したい場合、mojimoji が唯一の選択肢かもしれません。

import mojimoji
print(mojimoji.zen_to_han(u'アイウabc012'))
# アイウabc012
print(mojimoji.zen_to_han(u'アイウabc012', kana=False))
# アイウabc012
print(mojimoji.zen_to_han(u'アイウabc012', digit=False))
# アイウabc012
print(mojimoji.zen_to_han(u'アイウabc012', ascii=False))
# アイウabc012

print(mojimoji.han_to_zen(u'アイウabc012'))
# アイウabc012
print(mojimoji.han_to_zen(u'アイウabc012', kana=False))
# アイウabc012
print(mojimoji.han_to_zen(u'アイウabc012', digit=False))
# アイウabc012
print(mojimoji.han_to_zen(u'アイウabc012', ascii=False))
# アイウabc012

また、Python で半角・全角の変換を高速に行うによると、mojimoji も速度が最も速いです。

%%time
import mojimoji
import zenhan
import jctconv

s = u'アイオエオ012345' * 10

%time for n in range(1000000): mojimoji.zen_to_han(s)
>>> CPU times: user 3.90 s, sys: 0.03 s, total: 3.93 s Wall time: 3.97 s

%time for n in range(1000000): zenhan.z2h(s)
>>> CPU times: user 71.05 s, sys: 0.16 s, total: 71.22 s Wall time: 71.45 s

%time for n in range(1000000): jctconv.z2h(s)
>>> CPU times: user 19.75 s, sys: 0.06 s, total: 19.81 s Wall time: 19.86 s

unicodedata#

より一般的なニーズは実際には半角から全角への変換であるため、Python の標準ライブラリunicodedataで十分です。

%%time
import unicodedata

input = "アイオエオ012345" * 10
for n in range(1000000):
    unicodedata.normalize("NFKC", input)

>>> CPU times: total: 11.5 s Wall time: 11.6 s

標準ライブラリですが、変換速度は上記の mojimoji よりも遅いです。

また、Python 公式ドキュメントによると、NFCNFDNFKD の 3 つのモードがあり、ここでは詳細な説明は省略します実際には私も理解していないからです 233

以下にテストケースを提供します:

import unicodedata

HAN_MOJI = "ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロワヲンヴ゙゚"
ZEN_MOJI = "ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロワヲンヴ゙゚"
if ZEN_MOJI == unicodedata.normalize("NFKC", HAN_MOJI):
    print("OK")

性能をテストします:

%%time
input = "アイオエオ012345" * 10
for n in range(1000000):
    half_to_fullwidth(input)

>>> CPU times: total: 25.2 s Wall time: 25.3 s

速度と機能の観点から見ると、mojimoji が第一ですが、大多数の場合、半角から全角への変換だけが必要ですので、内蔵ライブラリの unicodedata をお勧めします。また、mojimoji は C++ 環境が必要で、パッケージ化時に少し面倒です。

その他#

一定範囲内の Unicode 文字を印刷する#

def print_characters(start_unicode):
    for i in range(start_unicode, start_unicode + 100):
        print(i+" : "chr(i))

# 関数を呼び出し、開始 Unicode コードを引数として渡す
start_unicode = int(input("開始の Unicode コードを入力してください: "))
print_characters(start_unicode)

参考#

Python で全角・半角を変換(mojimoji など):本文で言及したすべてのタイプの変換を非常に詳細に説明しています。

Python で半角・全角の変換を高速に行う:mojimoji の作者が自ら執筆したドキュメントで、3 つの一般的な半角から全角へのサードパーティライブラリの性能を比較しています。

Unicode 15.0 Character Code Charts:公式サイトで完全なコード表を確認できます。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。