27

ID3タグデータをCP-1251 / CP-1252からUTF-8に変換するために変異原を使用しています。Linuxでは問題はありません。ただし、WindowsではSetValue()、wx.TextCtrlを呼び出すとエラーが発生します。

UnicodeDecodeError:'ascii'コーデックは位置0のバイト0xc3をデコードできません:序数が範囲内にありません(128)

私が変異原から引き出している元の文字列(CP-1251でエンコードされていると想定)は次のとおりです。

u'\xc1\xe5\xeb\xe0\xff \xff\xe1\xeb\xfb\xed\xff \xe3\xf0\xee\xec\xf3'

これをUTF-8に変換してみました:

dd = d.decode('utf-8')

...さらに、デフォルトのエンコーディングをASCIIからUTF-8に変更します。

sys.setdefaultencoding('utf-8')

...しかし、同じエラーが発生します。

4

6 に答える 6

32

入力にcp1251が含まれていることが確実にわかっている場合は、次のことができます。

d.decode('cp1251').encode('utf8')
于 2011-09-26T12:53:30.020 に答える
5

文字列dはUnicode文字列であり、UTF-8でエンコードされた文字列ではありません。したがってdecode()、それはできませんencode()。UTF-8または必要なエンコーディングを使用する必要があります。

>>> d = u'\xc1\xe5\xeb\xe0\xff \xff\xe1\xeb\xfb\xed\xff \xe3\xf0\xee\xec\xf3'
>>> d
u'\xc1\xe5\xeb\xe0\xff \xff\xe1\xeb\xfb\xed\xff \xe3\xf0\xee\xec\xf3'
>>> print d
Áåëàÿ ÿáëûíÿ ãðîìó
>>> a.encode("utf-8")
'\xc3\x81\xc3\xa5\xc3\xab\xc3\xa0\xc3\xbf \xc3\xbf\xc3\xa1\xc3\xab\xc3\xbb\xc3\xad\xc3\xbf \xc3\xa3\xc3\xb0\xc3\xae\xc3\xac\xc3\xb3'

(これは、たとえば、UTF-8でエンコードされたファイルとして保存する必要がある場合に、すべての処理の最後に行うことです)。

入力が別のエンコーディングである場合は、その逆です。

>>> d = "Schoßhündchen"                 # native encoding: cp850
>>> d = "Schoßhündchen".decode("cp850") # decode from Windows codepage
>>> d                                   # into a Unicode string (now work with this!)
u'Scho\xdfh\xfcndchen'
>>> print d                             # it displays correctly if your shell knows the glyphs
Schoßhündchen
>>> d.encode("utf-8")                   # before output, convert to UTF-8
'Scho\xc3\x9fh\xc3\xbcndchen'
于 2011-09-28T08:01:15.080 に答える
4

dが正しいUnicode文字列の場合d.encode('utf-8')、エンコードされたUTF-8バイト文字列を生成します。ただし、印刷してテストしないでください。コードページのシェナニガンが原因で、正しく表示されない可能性があります。

于 2011-09-26T12:55:11.877 に答える
2

АлександрСтепаненкоの回答にコメントを追加したいのですが、私の評判ではまだ許可されていません。MP3タグをCP-1251からUTF-8に変換するという同様の問題があり、encode / decode/encodeのソリューションが機能しました。最初のエンコーディングを「latin-1」に置き換える必要があったことを除いて、これは基本的にUnicode文字列を実際のエンコーディングなしでバイトシーケンスに変換します。

print text.encode("latin-1").decode('cp1251').encode('utf8')

そして、例えば変異原を使用して節約するために、それをエンコードする必要はありません:

audio["title"] = title.encode("latin-1").decode('cp1251')
于 2017-07-22T15:56:52.257 に答える
1

私は正解を見つけるために一日の半分を失いました。したがって、外部ソースウィンドウからユニコード文字列を取得した場合(私の状況ではWebサイトから)エンコードされた1251は、Linuxコンソールに次のように表示されます。

u'\ u043a \ u043e \ u043c \ u043d \ u0430 \ u0442 \ u043d \ u0430 \ u044f \ u043a \ u0432 \ u0430 \ u0440 \ u0442 \ u0438 \ u0440 \ u0430 .....'

これは、データの正しいUnicode表示ではありません。だから、ティム・ピエツカーは正しい。最初にencode()し、次にdecode()してから、再度エンコードして正しいエンコードにする必要があります。

したがって、私の場合、この奇妙な行は「text」変数に保存され、次の行になります。

print text.encode("cp1251").decode('cp1251').encode('utf8')   

私にくれた:

"Своя2-хкомнатнаяквартирасотличнымремонтом...."

はい、それは私も夢中になります。しかし、それは機能します!

PSファイルに保存する場合も同じようにする必要があります。

some_file.write(text.encode("cp1251").decode('cp1251').encode('utf8'))
于 2016-10-26T11:57:21.873 に答える
0

私はこの応答でテキストのエンコード/デコードに関するいくつかの関連情報を提供しました:https ://stackoverflow.com/a/34662963/2957811

ここでそれに追加するには、「エンコードされた」と「デコードされた」の2つの可能な状態のいずれかでテキストを考えることが重要です。

「デコードされた」とは、文字操作(検索、大文字小文字の変換、部分文字列のスライス、文字数など)または表示(フォントのコードポイントの検索など)に使用できる、インタプリタ/ライブラリによる内部表現であることを意味します。グリフを描画します)が、実行中のプロセスに渡したり、プロセスから渡したりすることはできません。

「エンコードされた」とは、他のデータと同様に渡すことができるバイトストリームであることを意味しますが、操作や表示には役立ちません。

以前にシリアル化されたオブジェクトを操作したことがある場合は、「デコードされた」をメモリ内の有用なオブジェクトと見なし、「エンコードされた」をシリアル化されたバージョンと見なします。

'\xc1\xe5\xeb\xe0\xff \xff\xe1\xeb\xfb\xed\xff \xe3\xf0\xee\xec\xf3'おそらくcp1251でエンコードされた、エンコードされた(またはシリアル化された)バージョンです。このエンコーディングは、文字のシリアル化に使用される「言語」であり、メモリ内の文字を再作成するために必要であるため、正しくする必要があります。

これを現在のエンコーディング(cp1251)からPythonユニコード文字にデコードしてから、utf8バイトストリームとして再エンコードする必要があります。提案した回答者d.decode('cp1251').encode('utf8')はこの権利を持っていました。私はそれがうまくいく理由を説明するのを手伝いたいと思っています。

于 2016-01-07T19:17:09.690 に答える