我试图这样做,我发现了这个错误:
>>> import re
>>> x = 'Ingl\xeas'
>>> x
'Ingl\xeas'
>>> print x
Ingl�s
>>> x.decode('utf8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 4-5: unexpected end of data
>>> x.decode('utf8', 'ignore')
u'Ingl'
>>> x.decode('utf8', 'replace')
u'Ingl\ufffd'
>>> print x.decode('utf8', 'replace')
Ingl�
>>> print x.decode('utf8', 'xmlcharrefreplace')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
TypeError: don't know how to handle UnicodeDecodeError in error callback
当我使用print语句时,我想要:
>>> print x
u'Inglês'
欢迎任何帮助。
答案 0 :(得分:7)
在解码之前,您需要知道输入数据的编码方式。在你们的一些尝试中,你试图从UTF-8解码它,但是Python抛出一个异常,因为输入是无效的UTF-8。看起来它可能是拉丁语-1。这对我有用:
>>> x = 'Ingl\xeas'
>>> print x.decode('latin1')
Inglês
你提到“非ASCII HTML”。如果您正在编写Web服务器脚本并且从HTTP请求获取数据,则应检查Content-Type标头。在理想的世界中,它会告诉您客户端使用哪种编码方式来处理数据。请记住,客户端可能无法正常工作。
希望有所帮助!
答案 1 :(得分:0)
Ingl\xeas
不是UTF-8,而是(可能)Windows-1252-或latin1编码。所以你首先需要解码它。只有这样你才能将它编码为UTF-8。
因此:
>>> x = 'Ingl\xeas'
>>> print x.decode("cp1252")
Inglês
类似地,
>>> x.decode("cp1252").encode("UTF-8")
'Ingl\xc3\xaas'
这是正确的UTF-8表示。
顺便说一句,在Python 3中,你可以(至少在Windows下的交互式控制台中)输入
>>> x = 'Ingl\xeas'
>>> print (x)
Inglês
因为Python 3字符串总是Unicode字符串(不包括bytes
个对象)。
答案 2 :(得分:0)
一些观察结果:
(1)latin1
将解码任何8位字节而不抛出异常。仅在您用尽所有其他可能性时才使用latin1
。使用chardet帮助确定特定文件或网页或XML流的编码内容。
(2)基于非常有限的证据(一个字符)的可能替代方案:
>>> import unicodedata as ucd
>>> for codepage in range(1250, 1259):
... try:
... uc = "\xea".decode(str(codepage))
... except UnicodeDecodeError:
... pass
... if uc == u'\xea': print codepage, ucd.name(uc)
...
1252 LATIN SMALL LETTER E WITH CIRCUMFLEX
1254 LATIN SMALL LETTER E WITH CIRCUMFLEX
1256 LATIN SMALL LETTER E WITH CIRCUMFLEX
1258 LATIN SMALL LETTER E WITH CIRCUMFLEX
>>>
(3)范围U + 0080到U + 009F(包括)被分配给“C1控制字符”,unicode.org之外没有人知道它们可能有什么用途。无论你使用什么编码(甚至是UTF-8),在无异常解码到unicode之后,你还没有走出困境。检查该范围内的字符。如果您发现任何数据,您的数据已损坏,或者您选择的编码不正确。
def check_for_c1_control_characters(unicode_obj):
return any('\u0080' <= c <= '\u009F' for c in unicode_obj)
或使用正则表达式,如this example中所述,如何修复数据损坏的多种方式之一。