Pythonを使用してファイルの形式をUnicodeからASCIIに変換するにはどうすればよいですか?
質問
ファイルをUnicode形式で出力するサードパーティ製ツールを使用しています。ただし、ASCII形式にすることを好みます。ツールには、ファイル形式を変更する設定がありません。
Pythonを使用してファイル形式全体を変換する最良の方法は何ですか?
解決
unicode
関数を使用するだけでファイルを簡単に変換できますが、ASCIIに相当するものがないとUnicode文字で問題が発生します。
このブログは、 unicodedata
モジュールは、直接変換せずに文字を大まかに変換するように思われる対応するASCII値、たとえば
>>> title = u"Klüft skräms inför på fédéral électoral große"
は通常
に変換されますKlft skrms infr p fdral lectoral groe
これはかなり間違っています。ただし、 unicodedata
モジュールを使用すると、結果は元のテキストにはるかに近くなります。
>>> import unicodedata
>>> unicodedata.normalize('NFKD', title).encode('ascii','ignore')
'Kluft skrams infor pa federal electoral groe'
他のヒント
これはあなたが理解しているよりも深い問題だと思います。ファイルをUnicodeからASCIIに単純に変更するのは簡単ですが、すべてのUnicode文字を適切なASCII文字に変換することもできます(両方のエンコーディングで多くの文字は使用できません)。
このPython Unicodeチュートリアルでは、ASCIIに変換されたUnicode文字列に何が起こるかをよりよく理解できます: http://www.reportlab.com/i18n/python_unicode_tutorial.html
サイトからの便利な引用文は次のとおりです。
Python 1.6も" unicode"を取得します。 組み込み関数 エンコードを指定します:
> >>> unicode('hello') u'hello'
> >>> unicode('hello', 'ascii') u'hello'
> >>> unicode('hello', 'iso-8859-1') u'hello'
> >>>
これらの3つはすべて同じを返します 「Hello」のキャラクターが 3つのエンコーディングすべてに共通です。
ここで何かをエンコードしましょう 外側のヨーロッパのアクセント ASCII。コンソールに表示されるものは オペレーティングシステムに依存 ロケール; Windowsで入力できます ISO-Latin-1 >
> >>> a = unicode('André','latin-1')
> >>> a u'Andr\202'
鋭角文字eを入力できない場合、 文字列「Andr \ 202」を入力できます。 これは明確です。
Unicodeはすべての共通をサポートします 反復や 分割。私たちは彼らの上を走りません こちら。
ところで、これらはこの種の仕事をするためのLinuxコマンド iconv
です。
iconv -f utf8 -t ascii <input.txt >output.txt
エンコード変換を行うための簡単な(そして愚かな)コードをいくつか示します。入力ファイルはUTF-16であると想定しています(ただし、そうすべきではありません)(Windowsはこれを単に「Unicode」と呼びます)。
input_codec = 'UTF-16'
output_codec = 'ASCII'
unicode_file = open('filename')
unicode_data = unicode_file.read().decode(input_codec)
ascii_file = open('new filename', 'w')
ascii_file.write(unicode_data.write(unicode_data.encode(output_codec)))
Unicodeファイル内にASCII文字でもない文字がある場合、これは機能しないことに注意してください。認識できない文字を「?」に変換するには、次の操作を実行できます。
ascii_file.write(unicode_data.write(unicode_data.encode(output_codec, 'replace')))
より簡単な選択については、ドキュメントをご覧ください。さらに高度な処理が必要な場合は、 UNICODE Hammer をご覧ください。 Pythonクックブック。
これに似ています:
uc = open(filename).read().decode('utf8')
ascii = uc.decode('ascii')
ただし、ASCIIに変換できない文字がある場合、 UnicodeDecodeError
例外で失敗することに注意してください。
編集:Pete Karlが指摘したように、UnicodeからASCIIへの1対1のマッピングはありません。そのため、一部の文字は、情報を保存する方法で単純に変換できません。さらに、標準ASCIIは多かれ少なかれUTF-8のサブセットであるため、実際にデコードする必要さえありません。
非ASCII文字をスキップしてascii出力のみを出力したいという私の問題では、以下の解決策は本当にうまくいきました:
import unicodedata
input = open(filename).read().decode('UTF-16')
output = unicodedata.normalize('NFKD', input).encode('ASCII', 'ignore')
「Unicode」ファイル形式はないことに注意することが重要です。 Unicodeは、いくつかの異なる方法でバイトにエンコードできます。最も一般的にはUTF-8またはUTF-16。サードパーティのツールが出力しているものを知る必要があります。それがわかったら、異なるエンコーディング間の変換は非常に簡単です:
in_file = open("myfile.txt", "rb")
out_file = open("mynewfile.txt", "wb")
in_byte_string = in_file.read()
unicode_string = bytestring.decode('UTF-16')
out_byte_string = unicode_string.encode('ASCII')
out_file.write(out_byte_string)
out_file.close()
他の応答で述べたように、おそらくエンコードメソッドにエラーハンドラを提供したいと思うでしょう。エラーハンドラとして「置換」を使用するのは簡単ですが、ASCIIで表現できない文字が含まれている場合はテキストが破損します。
他の投稿者が指摘したように、ASCIIはUnicodeのサブセットです。
ただし、次の場合:
- レガシーアプリを持っている
- そのアプリのコードを制御しません
- 入力が必ずASCIIサブセットに分類される
次に、以下の例でその方法を示します。
mystring = u'bar'
type(mystring)
<type 'unicode'>
myasciistring = (mystring.encode('ASCII'))
type(myasciistring)
<type 'str'>