如何在Python中解码非Unicode字符?
我有一个字符串,比如 s = 'Chocolate Moelleux-M\xe8re'
。当我在做这个的时候:
In [14]: unicode(s)
---------------------------------------------------------------------------
UnicodeDecodeError Traceback (most recent call last)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 20: ordinal not in range(128)
同样,当我尝试用 s.decode()
来解码这个字符串时,它也返回了同样的错误。
In [13]: s.decode()
---------------------------------------------------------------------------
UnicodeDecodeError Traceback (most recent call last)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 20: ordinal not in range(128)
我该如何把这样的字符串解码成 Unicode 格式呢?
2 个回答
4
你需要告诉s.decode你使用的编码方式。在你的情况下,s.decode('latin-1')
看起来是合适的选择。
11
我遇到这个问题已经很多次了。这个问题是关于字符串使用了不同的编码方式。所以我写了一个方法,可以根据不同编码的一些特征,来智能地解码字符串。
def decode_heuristically(string, enc = None, denc = sys.getdefaultencoding()):
"""
Try to interpret 'string' using several possible encodings.
@input : string, encode type.
@output: a list [decoded_string, flag_decoded, encoding]
"""
if isinstance(string, unicode): return string, 0, "utf-8"
try:
new_string = unicode(string, "ascii")
return string, 0, "ascii"
except UnicodeError:
encodings = ["utf-8","iso-8859-1","cp1252","iso-8859-15"]
if denc != "ascii": encodings.insert(0, denc)
if enc: encodings.insert(0, enc)
for enc in encodings:
if (enc in ("iso-8859-15", "iso-8859-1") and
re.search(r"[\x80-\x9f]", string) is not None):
continue
if (enc in ("iso-8859-1", "cp1252") and
re.search(r"[\xa4\xa6\xa8\xb4\xb8\xbc-\xbe]", string)\
is not None):
continue
try:
new_string = unicode(string, enc)
except UnicodeError:
pass
else:
if new_string.encode(enc) == string:
return new_string, 0, enc
# If unable to decode,doing force decoding i.e.neglecting those chars.
output = [(unicode(string, enc, "ignore"), enc) for enc in encodings]
output = [(len(new_string[0]), new_string) for new_string in output]
output.sort()
new_string, enc = output[-1][1]
return new_string, 1, enc
另外,这个链接提供了关于编码的一些很好的反馈 - 为什么我们需要在Python脚本中使用sys.setdefaultencoding