2013-11-04 19 views
7

私はテキスト文書から非アスキー文字をすべて削除しようとしています。 https://pypi.python.org/pypi/Unidecodepython(3.3)でunidecodeを使う方法

文字列を受け入れ、すべての非ASCII文字を使用可能な最も近いASCII文字に変換する必要があります。私はこの同じモジュールをperlで簡単に使用しました。while (<input>) { $_ = unidecode($_); }を呼び出すだけで、これはperlモジュールの直接ポートです。ドキュメンテーションは同じ動作をする必要があることを示しています。

私はこれが単純なものだと確信していますが、問題の内容を知るために文字とファイルのエンコードについて十分理解していません。私のオリジナルファイルはUTF-8(UCS-2LEから変換)でエンコードされています。この問題は、私の知識のエンコーディングが不十分で、モジュールよりも誤った文字列を扱うことと関連があるかもしれません。私は無作為にコードを挿入し、私が今まで運がなかったエラーを検索することなく、私が知っているすべてを試しました。私はバイトモード(origfile = open('file.txt','r')で、元のファイルを開かない場合は

はここで、私はfor line in origfile:ラインからのエラーUnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position 1563: character maps to <undefined>を取得し、私のpython

from unidecode import unidecode 

def toascii(): 
    origfile = open(r'C:\log.convert', 'rb') 
    convertfile = open(r'C:\log.toascii', 'wb') 

    for line in origfile: 
     line = unidecode(line) 
     convertfile.write(line) 

    origfile.close() 
    convertfile.close() 

toascii(); 

です。

'rb'私は行からTypeError: ord() expected string length 1, but int foundを取得します。

行を文字列として宣言すると、line = unidecode(str(line))はファイルに書き込まれますが、正しくはありません。 \r\n'b'\xef\xbb\xbf[ 2013.10.05 16:18:01 ] User_Name > .\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\ \ n、\ rなど、ユニコード文字を何かに変換するのではなく書き出しています。

私は、上記のように、文字列に行を変換し、バイトモード'wb'でconvertfileを開くと、それは私がそれを文字列'wb'unidecode(line)を宣言しなくても、バイトモードで開く場合は、私が手にエラーにTypeError: 'str' does not support the buffer interface

を与えますTypeError: ord() expected string length 1, but int foundエラーが再び発生します。

答えて

8

unidecodeモジュールは、あなたが代わりにそれをバイナリデータを与えているユニコード文字列値と戻りのPython 3でUnicode文字列を受け付けます。テキストモードで入力テキストファイルをUnicodeまたは開くようにデコードし、ファイルに書き込む前にその結果をASCIIにエンコードするか、テキストモードで出力テキストファイルを開きます。

モジュールのドキュメントからの引用:

The module exports a single function that takes an Unicode object (Python 2.x) or string (Python 3.x) and returns a string (that can be encoded to ASCII bytes in Python 3.x)

重点鉱山。

これは動作するはずです:

def toascii(): 
    with open(r'C:\log.convert', 'r', encoding='utf8') as origfile, open(r'C:\log.toascii', 'w', encoding='ascii') as convertfile: 
     for line in origfile: 
      line = unidecode(line) 
      convertfile.write(line) 

を。これは、(あなたのサンプルラインから判断すると、正しいUTF8エンコーディングを使用して、)テキスト手口で入力ファイルを開き、テキスト手口(ASCIIへのエンコーディング)に書き込みます。

開いているファイルのエンコードを明示的に指定する必要があります。エンコードを省略すると、現在のシステムロケールが使用されます(locale.getpreferredencoding(False)呼び出しの結果)。通常、コードを移植する必要がある場合は、正しいコーデックになりません。

+0

最初に試してみると、str()を使用したときと同じ問題が発生します。つまり、 '\ r \ n \ xef \ xbb \ xbf'のような行になります。私はこれらのヒントを使って何ができるのか見ていきます。 – BeanBagKing

+1

@BeanBagKing:あなたが見る 'b '\ xef \ xbb \ xbf'はバイト値の表現です。これは、入力ファイルからデコードされたUnicode文字列値ではなく、 'str(bytevalue)'の結果を渡していることを意味します。 –

+0

が正しく、どういうわけか私の元のファイルはそれらの値で上書きされました。 UnicodeDecodeError: 'charmap'コーデックは1563のバイト0x90をデコードできません:cha racterはにマップします。私がバイトモードでファイルを開くと、長さが1の期待文字列が得られますが、intが見つかりました。これは私の元のファイルのエンコーディングでより根本的な問題でしょうか? – BeanBagKing

関連する問題