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

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

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

    ASCIIコードと互換性 UTF-16 • 16ビットで1文字(固定長)になるはずだった・・・ • 2^16 = 65536種では世界中の文字は表現不可 • サロゲートペアによる可変長 UTF-32 • 32ビットで1文字(固定長)
  5. 文字コードの変換? 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)
  6. 概念図 15 Python ファイル1 ファイル2 標準入出力 decode decode decode encode

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