15

次のユニコードと文字列は、明示的に定義されている場合、単独で存在できます。

>>> value_str='Andr\xc3\xa9'
>>> value_uni=u'Andr\xc3\xa9'

上記のような変数のみを割り当てた場合、Python 2.5または2.6でu'Andr\xc3\xa9'それを変換するにはどうすればよいですか?'Andr\xc3\xa9'

編集:

私は次のことをしました:

>>> value_uni.encode('latin-1')
'Andr\xc3\xa9'

これで問題が解決します。誰かが私に正確に何が起こっているのか説明できますか?

4

7 に答える 7

16

エンコーディングが混乱しているようです。あなたが本当に欲しいのはu'Andr\xe9'、と同等のものである可能性が高いようです'André'

しかし、あなたが持っているのは、誤ってデコードされたUTF-8エンコーディングのようです。Unicode文字列を通常の文字列に変換することで修正できます。最善の方法はわかりませんが、これはうまくいくようです。

>>> ''.join(chr(ord(c)) for c in u'Andr\xc3\xa9')
'Andr\xc3\xa9'

次に、正しくデコードします。

>>> ''.join(chr(ord(c)) for c in u'Andr\xc3\xa9').decode('utf8')
u'Andr\xe9'    

これで正しい形式になりました。

ただし、これを行う代わりに、可能であれば、データが最初に誤ってエンコードされた理由を解明し、そこでその問題を修正する必要があります。

于 2010-05-06T17:38:39.467 に答える
5

あなたは(コメントで)「」「それが私を困惑させていることです。元のアクセントから現在のアクセントにどのように移行しましたか?utf8とlatin1を使用したダブルエンコーディングと言えば、合計3つのエンコーディング(2 utf8)です。 + 1 latin1)?元の状態から現在の状態へのエンコードの順序は何ですか? "" "

Mark Byersの回答の中で、彼は「あなたが持っているのは、誤ってデコードされたUTF-8エンコーディングのようです」と述べています。あなたは彼の答えを受け入れました。しかし、あなたはまだ困惑していますか?OK、これがブローバイブローの説明です:

注:すべての文字列は(暗黙的に)を使用して表示されますrepr()unicodedata.name()内容を確認するために使用されます。そうすれば、コンソールエンコーディングのバリエーションによって、文字列の解釈が混乱することはありません。

初期状態:u1という名前のUnicodeオブジェクトがあります。e-acuteが含まれています:

>>> u1 = u'\xe9'
>>> import unicodedata as ucd
>>> ucd.name(u1)
'LATIN SMALL LETTER E WITH ACUTE'

u1をUTF-8としてエンコードし、結果に次の名前を付けます。

>>> s = u1.encode('utf8')
>>> s
'\xc3\xa9'

latin1-を使用してsをデコードします-誤って; sは、latin1ではなくutf8を使用してエンコードされました。結果は無意味なゴミです。

>>> u2 = s.decode('latin1')
>>> u2
u'\xc3\xa9'
>>> ucd.name(u2[0]); ucd.name(u2[1])
'LATIN CAPITAL LETTER A WITH TILDE'
'COPYRIGHT SIGN'
>>>

理解してください:unicode_object.encode('x').decode('y)x!=yが通常[下記の注を参照]ナンセンスである場合。運が良ければ例外が発生します。運が悪ければ、それは静かにぎこちないものを作ります。また、ジブリッシュを黙って作成することはバグではないことを理解してください。Python(または他の言語)がナンセンスがコミットされたことを検出できる一般的な方法はありません。これは特にlatin1が関係する場合に当てはまります。これは、256個のコードポイントすべてが最初の256個のUnicodeコードポイントと1対1でマップされるため、str_object.decode('latin1')からUnicodeDecodeErrorを取得することができないためです。

もちろん、異常に(異常であることを願っています)gibberish_unicode_object.encode('y').decode('x')、質問に対するさまざまな回答で提案されているように、そのようなナンセンスを元に戻す必要があるかもしれません。

于 2010-05-07T12:48:10.080 に答える
4

がある場合u'Andr\xc3\xa9'、それは間違ったエンコーディングのバイト文字列からデコードされたUnicode文字列です。正しいエンコーディングはUTF-8です。正しくデコードできるようにバイト文字列に変換し直すには、発見したトリックを使用できます。latin1Unicodeの最初の256コードポイントは、ISO-8859-1(エイリアス)エンコーディングを使用した1:1マッピングです。それで:

>>> u'Andr\xc3\xa9'.encode('latin1')
'Andr\xc3\xa9'

これで、次のコマンドで正しくデコードできるバイト文字列になりますutf8

>>> 'Andr\xc3\xa9'.decode('utf8')
u'Andr\xe9'
>>> print 'Andr\xc3\xa9'.decode('utf8')
André

ワンステップで:

>>> print u'Andr\xc3\xa9'.encode('latin1').decode('utf8')
André
于 2010-05-07T03:43:40.307 に答える
4

value_uni.encode('utf8')または必要なエンコーディング。

http://docs.python.org/library/stdtypes.html#str.encodeを参照してください

于 2010-05-06T17:29:38.787 に答える
1

OPはasciiまたはutf-8に変換されていません。そのため、提案されたencode方法は機能しません。これを試して:

v = u'Andr\xc3\xa9'
s = ''.join(map(lambda x: chr(ord(x)),v))

chr(ord(x))ビジネスはUnicode文字の数値(アプリケーションの1バイトに収まる)を取得します。この呼び出し''.joinは、intのリストを通常の文字列に変換するイディオムです。もっとエレガントな方法があることは間違いありません。

于 2010-05-06T17:59:51.207 に答える
0

簡単な説明。str型は、0から255の範囲の文字のみを保持できます。ユニコード(はるかに広い範囲の文字を含むことができる)をstrに格納する場合は、最初にユニコードをstrに適した形式(UTF-8など)にエンコードする必要があります。

この呼び出しを行うには、strオブジェクトでメソッドencodeを呼び出し、引数として、たとえば、必要なエンコーディングを指定しますthis_is_str = value_uni.encode('utf-8')

Unicodeの処理に関するより長くより詳細な(そして言語に依存しない)記事をここで読むことができます:絶対最小すべてのソフトウェア開発者は絶対に、積極的にUnicodeと文字セットについて知っている必要があります(言い訳はありません!)

もう1つの優れた記事(今回はPython固有):Unicode HOWTO

于 2010-05-06T17:36:26.887 に答える
-1

のようです

str(value_uni)

うまくいくはずです...少なくとも、私が試したときはうまくいきました。

編集:これが機能するのは、私のシステムのデフォルトのエンコーディングが、私が知る限り、ISO-8859-1(Latin-1)であるためです。したがって、これのプラットフォームに依存しないバージョンについては、

value_uni.encode('latin1')
于 2010-05-06T17:27:35.750 に答える