Python 如何用十六进制字符解码 unicode
Python how to decode unicode with hex characters
我从网络抓取脚本中提取了如下字符串:
u'\xe3\x80\x90\xe4\xb8\xad\xe5\xad\x97\xe3\x80\x91'
我想用 utf-8 解码 u'\xe3\x80\x90\xe4\xb8\xad\xe5\xad\x97\xe3\x80\x91'
。
使用 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)
请问如何正确解码字符串?
感谢您的帮助。
只需将 msg 保留为字符串而不是 unicode。
msg = '\xe3\x80\x90\xe4\xb8\xad\xe5\xad\x97\xe3\x80\x91'
result = msg.decode('utf8')
也许您应该修复抓取脚本,Unicode 字符串应该已经包含 u'【中字】'
(u'\u3010\u4e2d\u5b57\u3011'
),而不是原始的 UTF-8 字节。
要将msg
转换为正确的编码,首先需要将错误的Unicode字符串转回字节串(将其编码为Latin-1),然后 将其解码为 UTF-8:
>>> print msg.encode('latin1').decode('utf-8')
【中字】
的问题
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,因此它 "helpfully" 假定您要使用默认的 ASCII 编解码器对 msg
进行编码,因此可以使用 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)中的字符。
这里有一些 Python2 代码可以说明这一点:
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
您可能会发现这篇文章很有帮助:Pragmatic Unicode,由 SO 资深人士 Ned Batchelder 撰写。
除非你被迫使用 Python 2 我强烈建议你切换到 Python 3. 它会大大减少处理 Unicode 的痛苦。
我从网络抓取脚本中提取了如下字符串:
u'\xe3\x80\x90\xe4\xb8\xad\xe5\xad\x97\xe3\x80\x91'
我想用 utf-8 解码 u'\xe3\x80\x90\xe4\xb8\xad\xe5\xad\x97\xe3\x80\x91'
。
使用 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)
请问如何正确解码字符串?
感谢您的帮助。
只需将 msg 保留为字符串而不是 unicode。
msg = '\xe3\x80\x90\xe4\xb8\xad\xe5\xad\x97\xe3\x80\x91'
result = msg.decode('utf8')
也许您应该修复抓取脚本,Unicode 字符串应该已经包含
u'【中字】'
(u'\u3010\u4e2d\u5b57\u3011'
),而不是原始的 UTF-8 字节。要将
msg
转换为正确的编码,首先需要将错误的Unicode字符串转回字节串(将其编码为Latin-1),然后 将其解码为 UTF-8:>>> print msg.encode('latin1').decode('utf-8') 【中字】
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,因此它 "helpfully" 假定您要使用默认的 ASCII 编解码器对 msg
进行编码,因此可以使用 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)中的字符。
这里有一些 Python2 代码可以说明这一点:
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
您可能会发现这篇文章很有帮助:Pragmatic Unicode,由 SO 资深人士 Ned Batchelder 撰写。
除非你被迫使用 Python 2 我强烈建议你切换到 Python 3. 它会大大减少处理 Unicode 的痛苦。