Python如何使用十六进制字符解码unicode

发布于 2021-01-29 14:57:05

我已经从Web爬网脚本中提取了一个字符串,如下所示:

u'\xe3\x80\x90\xe4\xb8\xad\xe5\xad\x97\xe3\x80\x91'

我想u'\xe3\x80\x90\xe4\xb8\xad\xe5\xad\x97\xe3\x80\x91'用utf-8解码。使用http://ddecode.com/hexdecoder/,我可以看到结果是'【中字】'

我尝试使用以下语法,但失败了。

msg = u'\xe3\x80\x90\xe4\xb8\xad\xe5\xad\x97\xe3\x80\x91'
result = msg.decode('utf8')

错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-11: ordi
nal not in range(128)

请问如何正确解码字符串?

感谢帮助。

关注者
0
被浏览
108
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    问题所在

    msg = u'\xe3\x80\x90\xe4\xb8\xad\xe5\xad\x97\xe3\x80\x91'
    result = msg.decode('utf8')
    

    是您正在尝试解码Unicode。那真的没有道理。您可以 Unicode编码为某种编码类型,也可以将字节字符串解码 Unicode。

    当你做

    msg.decode('utf8')
    

    Python
    2看到这msg是Unicode。它知道它无法解码Unicode,因此“有帮助”地假定您要msg使用默认的ASCII编解码器进行编码,以便可以使用UTF-8编解码器将该转换的结果解码为Unicode。Python
    3的行为更加明智:代码会因以下原因而失败

    AttributeError: 'str' object has no attribute 'decode'
    

    kennytm的答案中给出的技术:

    msg.encode('latin1').decode('utf-8')
    

    之所以起作用,是因为小于256的Unicode代码点直接对应于Latin1编码中的字符(也称为ISO
    8859-1)。

    这是一些Python 2代码,说明了这一点:

    for i in xrange(256):
        lat = chr(i)
        uni = unichr(i)
        assert lat == uni.encode('latin1')
        assert lat.decode('latin1') == uni
    

    这是等效的Python 3代码:

    for i in range(256):
        lat = bytes([i])
        uni = chr(i)
        assert lat == uni.encode('latin1')
        assert lat.decode('latin1') == uni
    

    您可能会发现这篇文章很有帮助:实用Unicode,由SO老手Ned
    Batchelder编写。

    除非您被迫使用Python 2,否则我强烈建议您切换到Python3。这将大大减少处理Unicode的痛苦。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看