あなたには3つか4つか5つの問題があります...しかしrepr()
そしてunicodedata.name()
あなたの友達です。の結果を伝達するさまざまなコンソールエンコーディングを持つ人々によって引き起こされる混乱なしに、それらはあなたが得たものを正確にあなたに明確に示しますprint fubar
。
概要:(a)Unicodeオブジェクトから開始し、それにunquote関数を適用するか、(b)strオブジェクトから開始し、コンソールエンコーディングがUTF-8ではないかのいずれかです。
あなたが言うようにあなたがユニコードオブジェクトから始めるならば:
>>> s0 = u'%C3%A7%C3%B6asd+fjkls%25asd'
>>> print repr(s0)
u'%C3%A7%C3%B6asd+fjkls%25asd'
これは偶然のナンセンスです。これに適用urllibX.unquote_YYYY()
すると、別の意味のないUnicodeオブジェクト(u'\xc3\xa7\xc3\xb6asd+fjkls%asd'
)が表示され、印刷時に表示される症状が発生します。元のUnicodeオブジェクトをすぐにstrオブジェクトに変換する必要があります。
>>> s1 = s0.encode('ascii')
>>> print repr(s1)
'%C3%A7%C3%B6asd+fjkls%25asd'
次に、引用符を外す必要があります。
>>> import urllib2
>>> s2 = urllib2.unquote(s1)
>>> print repr(s2)
'\xc3\xa7\xc3\xb6asd+fjkls%asd'
その最初の4バイトを見ると、UTF-8でエンコードされています。そうすると、コンソールがUTF-8を期待している場合print s2
は問題ないように見えますが、ISO-8859-1(別名latin1)を期待している場合は、症候性のゴミが表示されます(最初の文字はAチルダになります)。その考えを少しの間駐車して、Unicodeオブジェクトに変換しましょう。
>>> s3 = s2.decode('utf8')
>>> print repr(s3)
u'\xe7\xf6asd+fjkls%asd'
それを調べて、実際に何が得られるかを確認します。
>>> import unicodedata
>>> for c in s3[:6]:
... print repr(c), unicodedata.name(c)
...
u'\xe7' LATIN SMALL LETTER C WITH CEDILLA
u'\xf6' LATIN SMALL LETTER O WITH DIAERESIS
u'a' LATIN SMALL LETTER A
u's' LATIN SMALL LETTER S
u'd' LATIN SMALL LETTER D
u'+' PLUS SIGN
あなたが期待したと言ったことのように見えます。次に、コンソールに表示するかどうかという問題が発生します。注:「cp850」が表示されても、びっくりしないでください。私はこれを移植可能に行っており、たまたまWindowsのコマンドプロンプトでこれを行っています。
>>> import sys
>>> sys.stdout.encoding
'cp850'
>>> print s3
çöasd+fjkls%asd
注:Unicodeオブジェクトは、sys.stdout.encodingを使用して明示的にエンコードされました。幸い、のすべてのUnicode文字はs3
、そのエンコーディング(およびcp1252とlatin1)で表現できます。