use*_*287 12 url-encoding python-unicode
我有一个unicode字符串'%C3%A7%C3%B6asd+fjkls%25asd',我想解码这个字符串.
我用过,urllib.unquote_plus(str)但它的工作错了.
çöasd+fjkls%asdçöasd fjkls%asd双重编码的utf-8字符(%C3%A7和%C3%B6)被解码错误.
我的python版本在linux发行版下是2.7.获得预期结果的最佳方法是什么?
Joh*_*hin 29
你有3个或4个或5个问题...但repr()并unicodedata.name()是你的朋友; 他们毫不含糊地向你展示了你所拥有的东西,没有人们用不同的控制台编码来传达结果的混乱print fubar.
总结:要么(a)从unicode对象开始并将unquote函数应用于该对象,或者(b)从str对象开始,并且控制台编码不是UTF-8.
如果你说你开始使用unicode对象:
>>> s0 = u'%C3%A7%C3%B6asd+fjkls%25asd'
>>> print repr(s0)
u'%C3%A7%C3%B6asd+fjkls%25asd'
Run Code Online (Sandbox Code Playgroud)
这是一个偶然的废话.如果你申请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'
Run Code Online (Sandbox Code Playgroud)
那么你应该取消它:
>>> import urllib2
>>> s2 = urllib2.unquote(s1)
>>> print repr(s2)
'\xc3\xa7\xc3\xb6asd+fjkls%asd'
Run Code Online (Sandbox Code Playgroud)
查看它的前4个字节,它以UTF-8编码.如果你这样做print s2,如果你的控制台期望UTF-8,它看起来会好的,但是如果你期待ISO-8859-1(也就是latin1),你会看到你的症状性垃圾(第一个字符将是A-tilde).让我们停下来思考片刻并将其转换为Unicode对象:
>>> s3 = s2.decode('utf8')
>>> print repr(s3)
u'\xe7\xf6asd+fjkls%asd'
Run Code Online (Sandbox Code Playgroud)
并检查它,看看我们实际得到了什么:
>>> 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
Run Code Online (Sandbox Code Playgroud)
看起来就像你说的那样.现在我们来讨论在控制台上显示它的问题.注意:当你看到"cp850"时不要惊慌失措; 我正在这样做,并恰好在Windows上的命令提示符中执行此操作.
>>> import sys
>>> sys.stdout.encoding
'cp850'
>>> print s3
çöasd+fjkls%asd
Run Code Online (Sandbox Code Playgroud)
注意:使用sys.stdout.encoding显式编码unicode对象.幸运的是,所有unicode字符s3都可以在该编码中表示(以及cp1252和latin1).
Dun*_*can 12
使用unquote或unquote_plus将给你一个字节字符串.如果你想要一个Unicode字符串,那么你必须将字节字符串解码为unicode:
>>> print(urllib.unquote_plus('%C3%A7%C3%B6asd+fjkls%25asd').decode('utf8'))
çöasd fjkls%asd
>>>
Run Code Online (Sandbox Code Playgroud)
和....相比:
>>> print(urllib.unquote_plus('%C3%A7%C3%B6asd+fjkls%25asd'))
çöasd fjkls%asd
>>>
Run Code Online (Sandbox Code Playgroud)
请注意,您的输入字符串必须是字节字符串:如果您将unicode传递给unquote/unquote_plus那么您将会有点混乱.如果是这种情况,那么先编码:
>>> print(urllib.unquote_plus(u'%C3%A7%C3%B6asd+fjkls%25asd'.encode('ascii')).decode('utf8'))
çöasd fjkls%asd
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14176 次 |
| 最近记录: |