Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pythonにおける日本語処理

 Pythonにおける日本語処理

Sho Iizuka

March 25, 2016
Tweet

More Decks by Sho Iizuka

Other Decks in Programming

Transcript

  1. Pythonにおける日本語処理
    TB12E008
    飯塚 翔
    1

    View Slide

  2. 目次
    2
    1. 文字コードについて
    2. Pythonで日本語を処理する

    View Slide

  3. 目次
    3
    1. 文字コードについて
    2. Pythonで日本語を処理する

    View Slide

  4. 文字コードとは
    4
    0x00003042
    0x0001F604
    0x00000041

    A
    バイナリ(UTF-32)
    文字
    文字コード

    View Slide

  5. ASCIIコード
    5
    http://d.hatena.ne.jp/zariganitosh/20150209/ascii_code_secrets
    制御コード
    記号
    数字
    大文字
    小文字

    View Slide

  6. 日本語文字コード
    6
    https://ja.wikipedia.org/wiki/文字コード

    View Slide

  7. どうしてこうなった・・・
    7
    • 文字集合が違う
    ⇒ 収録されている文字が違う!
    • 他の国の文字が入っていない
    (例:ハングル,アラビア語)
    • 戸籍用の漢字
    (例:「さいとう」の斉,斎,齋,・・・)
    • 符号化方式が違う
    ⇒ 文字をバイナリとして表現する方法が違う!
    • 1文字あたり何バイト?
    • 固定長?可変長?

    View Slide

  8. 固定長・可変長
    8
    固定長
    可変長
    0~255
    例:1文字1バイト
    0~65535
    例:1文字2バイト 例:1文字4バイト
    0~42億くらい
    0~127
    A. 1文字1バイトの文字
    B. 1文字2バイトの文字 192~223 128~191
    ×
    C. 1文字3バイトの文字 224~239 128~191
    × 128~191
    ×
    D. 1文字4バイトの文字 240~247 ×(略)

    View Slide

  9. UnicodeとUTF-8 / UTF-16 / UTF-32
    9
    • 文字集合が違う
    ⇒ 収録されている文字が違う!
    • 他の国の文字が入っていない
    (例:ハングル,アラビア語)
    • 戸籍用の漢字
    (例:「さいとう」の斉,斎,齋,・・・)
    • 符号化方式が違う
    ⇒ 文字をバイナリとして表現する方法が違う!
    • 固定長?可変長?
    • 1文字あたり何バイト?
    目的「世界中の全ての文字を表現できる文字コードを作る」
    Unicode
    UTF-8, 16, 32

    View Slide

  10. UTF-8 / UTF-16 / UTF-32
    10
    UTF-8
    • 8ビットを単位とした可変長
    • ASCIIコードと互換性
    UTF-16
    • 16ビットで1文字(固定長)になるはずだった・・・
    • 2^16 = 65536種では世界中の文字は表現不可
    • サロゲートペアによる可変長
    UTF-32
    • 32ビットで1文字(固定長)

    View Slide

  11. 目次
    11
    1. 文字コードについて
    2. Pythonで日本語を処理する

    View Slide

  12. 句読点チェッカを作る
    12
    punct_checker.py
    1. Shift_JISで書かれた日本語ファイルを読み込む
    2. テキスト中に「、。,.」があるかチェックし,
    標準出力に出力する
    punct_normalizer.py
    1. Shift_JISで書かれた日本語ファイルを読み込む
    2. 「,.」を「、。」に直して
    別のファイルにUTF-8で書き込む

    View Slide

  13. データの流れ
    13
    Python
    入力ファイル
    出力ファイル
    標準出力
    (stdout)
    Shift_JIS
    Windowsなら
    Shift_JIS
    UTF-8

    View Slide

  14. 文字コードの変換?
    14
    流儀1:↓プログラマがこんなのをがんばって書く
    流儀2:文字列は,自分の文字コードを知っている
    流儀3:標準文字コード(例:Unicode)がある
    input_data = read("Shift_JIS")
    output_data = convert(input_data, "UTF-8")
    write(output_data)
    input_dataはShift_JIS
    だからShift_JISから
    UTF-8に変換
    data = read("Shift_JIS")
    write(data, "UTF-8")
    Shift_JISから
    標準文字コードに変換
    標準文字コードから
    UTF-8に変換
    input_data = read()
    output_data = convert(input_data, "Shift_JIS", "UTF-8")
    write(output_data)

    View Slide

  15. 概念図
    15
    Python
    ファイル1
    ファイル2
    標準入出力
    decode
    decode
    decode
    encode
    encode
    encode
    Unicodeを
    表現可能な型
    例:EUC-JP
    例:UTF-8
    例:Shift_JIS

    View Slide

  16. punct_checker.py
    16
    # coding: UTF-8
    maru = False
    ten = False
    period = False
    comma = False
    f = open('input.txt', 'r', encoding='Shift_JIS')
    for line in f:
    if '。' in line:
    maru = True
    if '、' in line:
    ten = True
    # 略
    f.close()
    if maru:
    print('「。」が含まれています')
    else:
    print('「。」が含まれていません')
    # 略
    1行ずつ読み込む
    ソースコードの
    文字コード
    1行目に文字コードが無いと
    Pythonが理解できない
    ファイルの
    文字コード
    標準出力の文字コードは設定済み

    View Slide

  17. punct_normalizer.py
    17
    # coding: UTF-8
    lines = []
    with open('input.txt', 'r', encoding='Shift_JIS') as f:
    for line in f:
    lines.append(line)
    with open('output.txt', 'w', encoding='UTF-8') as f:
    for line in lines:
    line = line.replace('.', '。')
    line = line.replace(',', '、')
    print(line, file=f)
    ファイルに書き込み
    with open(...) as f: を使うと
    自動でf.close()
    replace:置換

    View Slide

  18. Python2系の思い出
    18
    # coding: UTF-8
    lines = []
    with open('input.txt', 'r') as f:
    for line in f:
    lines.append(line.decode('Shift_JIS'))
    with open('output.txt', 'w') as f:
    for line in lines:
    line = line.replace(u'.', u'。')
    line = line.replace(u',', u'、')
    f.write(line.encode('UTF-8'))
    decodeはプログラマの
    責任
    ASCII以外の文字コードなんて知らん!!
    (codecsモジュールを使う方法もある)
    encodeもプログラマの
    責任
    非ASCII文字には
    u””を付ける

    View Slide