Pythonにおける日本語処理

 Pythonにおける日本語処理

0c58c2a17fb8306d9e5a2c9441d978d7?s=128

Sho Iizuka

March 25, 2016
Tweet

Transcript

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

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

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

  4. 文字コードとは 4 0x00003042 0x0001F604 0x00000041 あ A バイナリ(UTF-32) 文字 文字コード

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

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

  7. どうしてこうなった・・・ 7 • 文字集合が違う ⇒ 収録されている文字が違う! • 他の国の文字が入っていない (例:ハングル,アラビア語) •

    戸籍用の漢字 (例:「さいとう」の斉,斎,齋,・・・) • 符号化方式が違う ⇒ 文字をバイナリとして表現する方法が違う! • 1文字あたり何バイト? • 固定長?可変長?
  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 ×(略)
  9. UnicodeとUTF-8 / UTF-16 / UTF-32 9 • 文字集合が違う ⇒ 収録されている文字が違う!

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

    ASCIIコードと互換性 UTF-16 • 16ビットで1文字(固定長)になるはずだった・・・ • 2^16 = 65536種では世界中の文字は表現不可 • サロゲートペアによる可変長 UTF-32 • 32ビットで1文字(固定長)
  11. 目次 11 1. 文字コードについて 2. Pythonで日本語を処理する

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

    Shift_JISで書かれた日本語ファイルを読み込む 2. 「,.」を「、。」に直して 別のファイルにUTF-8で書き込む
  13. データの流れ 13 Python 入力ファイル 出力ファイル 標準出力 (stdout) Shift_JIS Windowsなら Shift_JIS

    UTF-8
  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)
  15. 概念図 15 Python ファイル1 ファイル2 標準入出力 decode decode decode encode

    encode encode Unicodeを 表現可能な型 例:EUC-JP 例:UTF-8 例:Shift_JIS
  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が理解できない ファイルの 文字コード 標準出力の文字コードは設定済み
  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:置換
  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””を付ける