您遇到了乱码字符串问题;文本使用一种编码方式进行编码,但是却使用另一种编码方式进行解码。
在这种情况下,您的文本使用Windows 1252代码页进行解码;文本中的U+20AC欧元符号是CP1252 Mojibakes的典型特征。原始编码可能是GB*系列的中文编码之一,或者是多次往返的UTF-8 - CP1252 Mojibake。我无法确定其中哪一个,因为我不能读取中文,也没有您的完整数据;CP1252 Mojibakes包括不可打印字符,如0x81和0x8D字节,这些字符可能在您发布问题时丢失了。
我会安装
ftfy
项目;它不能修复GB*编码(我
请求该项目添加支持),但它包括一个名为
sloppy-windows-1252
的新编解码器,可以让您使用该编解码器逆转错误解码:
>>> import ftfy # registers extra codecs on import
>>> text = u'袋è¢âdcx€¹Ã¤Â¸Å½Ã¦Å“‹å‹们çâ€ÂµÃ¥ÂÂå•â€'
>>> print text.encode('sloppy-windows-1252').decode('gb2312', 'replace')
猫垄�姑�⑩dcx�盲赂沤忙��姑ヂ�姑ぢ宦�р�得ヂ�氓�⑩�
>>> print text.encode('sloppy-windows-1252').decode('gbk', 'replace')
猫垄鈥姑�⑩dcx�盲赂沤忙艙鈥姑ヂ鈥姑ぢ宦�р�得ヂ�氓鈥⑩�
>>> print text.encode('sloppy-windows-1252').decode('gb18030', 'replace')
猫垄鈥姑⑩dcx�盲赂沤忙艙鈥姑ヂ鈥姑ぢ宦р�得ヂ氓鈥⑩�
>>> print text.encode('sloppy-windows-1252').decode('utf8', 'ignore').encode('sloppy-windows-1252').decode('utf8', 'replace')
袋�dcx与朋�们���
�
U+FFFD REPLACEMENT CHARACTER 表示解码并不完全成功,但这可能是由于您复制的字符串中缺少任何不可打印或使用0x81或0x8D字节的内容造成的。
您可以尝试使用以下方式修复数据:从文件数据开始,先编码为sloppy-windows-1252
,然后解码为GB *编解码之一,或者进行两次UTF-8往返并查看哪个最合适。
如果这还不够好(您无法修复数据),则可以使用ftfy.badness.sequence_weirdness()
函数来尝试检测问题:
>>> from ftfy.badness import sequence_weirdness
>>> sequence_weirdness(text)
9
>>> sequence_weirdness(u'元大寶來證券')
0
>>> sequence_weirdness(u'John Dove')
0
Mojibakes在“序列奇异性”尺度上得分很高。你可以尝试找到一个适当的阈值来确定哪些数据最可能已经损坏了。
然而,我认为我们可以使用非零返回值作为另一个测试的起点。英文文本应该在该尺度上得分为0,中文文本也应该是如此。混合中英文的文本仍然可以得分超过0,但是你无法将那些中文文本编码为CP-1252编解码,而你可以对损坏的文本进行编码。
from ftfy.badness import sequence_weirdness
def is_valid_unicode_str(text):
if not sequence_weirdness(text):
return True
try:
text.encode('sloppy-windows-1252')
except UnicodeEncodeError:
return True
else:
return False
codecs.open()
已经将其解码为Unicode字符串。 - Martijn Pietersftfy
能做些什么来理解你所拥有的字符串。 - Martijn Pieters猫垄姑⑩dcx盲赂沤忙姑ヂ姑ぢ宦р得ヂ氓⑩
或猫垄鈥姑⑩dcx盲赂沤忙艙鈥姑ヂ鈥姑ぢ宦р得ヂ氓鈥⑩
或猫垄鈥姑⑩dcx盲赂沤忙艙鈥姑ヂ鈥姑ぢ宦р得ヂ氓鈥⑩
(GB2312、GBK和GB18030)。我会进一步查看。 - Martijn Pietersprint repr(broken_value)
的输出?这样,任何不可打印和非 ASCII 字节将被包含为转义序列,使我们能够准确地重新创建该值。 - Martijn Pieters