web-dev-qa-db-ja.com

Pythonを使用してファイルの形式をUnicodeからASCIIに変換するにはどうすればよいですか?

Unicode形式でファイルを出力するサードパーティのツールを使用しています。しかし、私はそれがASCIIであることを好みます。ツールには、ファイル形式を変更するための設定がありません。

Pythonを使用してファイル形式全体を変換する最良の方法は何ですか?

22
Ray Vega

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'
44
ConroyP

これはあなたが思っているよりも深い問題だと思います。ファイルを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'
> >>>

'Hello'の文字は、3つのエンコーディングすべてに共通であるため、これら3つすべてが同じものを返します。

それでは、ASCIIの外にあるヨーロッパのアクセントで何かをエンコードしましょう。コンソールに表示される内容は、オペレーティングシステムのロケールによって異なる場合があります。 WindowsではISO-Latin-1を入力できます。

> >>> a = unicode('André','latin-1')
> >>> a u'Andr\202'

鋭い文字eを入力できない場合は、文字列「Andr\202」を入力できます。これは明確です。

Unicodeは、反復や分割などの一般的な操作をすべてサポートしています。ここではそれらにぶつかることはありません。

11
Pete Karl II

ちなみに、これらはこの種の仕事をするためのLinuxコマンドiconvです。

iconv -f utf8 -t ascii <input.txt >output.txt
3
kev

非ASCII文字をスキップして、ASCII出力のみを出力したいという私の問題では、以下の解決策が非常にうまく機能しました。

    import unicodedata
    input = open(filename).read().decode('UTF-16')
    output = unicodedata.normalize('NFKD', input).encode('ASCII', 'ignore')
2
Vijay

このような:

uc = open(filename).read().decode('utf8')
ascii = uc.decode('ascii')

ただし、ASCIIに変換できない文字がある場合、これはUnicodeDecodeError例外でfailになることに注意してください。

編集:Pete Karlが指摘したように、UnicodeからASCIIへの1対1のマッピングはありません。そのため、一部の文字は、情報を保持する方法で変換できないだけです。さらに、標準ASCIIは多かれ少なかれUTF-8のサブセットであるため、実際にはデコードを行う必要さえありません。

2
Dan Lenski

エンコーディング変換を行うためのいくつかの単純な(そして愚かな)コードがあります。入力ファイルが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')))

より簡単な選択については、 ドキュメント を確認してください。より洗練された何かをする必要がある場合は、Python Cookbookで NICODE Hammer をチェックしてください。

2
giltay

「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()

他の返信で述べたように、encodeメソッドにエラーハンドラーを提供することをお勧めします。エラーハンドラとして「replace」を使用するのは簡単ですが、ASCIIで表現できない文字が含まれている場合はテキストが壊れます。

0
Jerry Hill

他の投稿者が指摘しているように、ASCIIはユニコードのサブセットです。

ただし、次の場合:

  • レガシーアプリを持っている
  • そのアプリのコードを制御していません
  • 入力がASCIIサブセットに分類されることを確認してください

次に、以下の例はそれを行う方法を示しています。

mystring = u'bar'
type(mystring)
    <type 'unicode'>

myasciistring = (mystring.encode('ASCII'))
type(myasciistring)
    <type 'str'>
0
mikemaccana