我有一个文件,大部分是UTF-8,但一些Windows-1252字符也找到了他们的方式。
我创建了一个表来从Windows-1252(cp1252)字符映射到它们的Unicode对应字符,并希望使用它来修复错误编码的字符,例如
cp1252_to_unicode = {
"\x85": u'\u2026', # …
"\x91": u'\u2018', # ‘
"\x92": u'\u2019', # ’
"\x93": u'\u201c', # “
"\x94": u'\u201d', # ”
"\x97": u'\u2014' # —
}
for l in open('file.txt'):
for c, u in cp1252_to_unicode.items():
l = l.replace(c, u)
但尝试以这种方式进行替换会导致引发unicodedecoderor,例如:
"\x85".replace("\x85", u'\u2026')
UnicodeDecodeError: 'ascii' codec can't decode byte 0x85 in position 0: ordinal not in range(128)
有什么解决办法吗?
如果您尝试将此字符串解码为utf-8,如您所知,您将得到一个“UnicodeDecode”错误,因为这些虚假的cp1252字符是无效的utf-8-
但是,Python codecs允许您使用codecs.register嫒error函数注册一个callback to handle encoding/decoding错误-它为UnicodeDecodeerror获取一个参数-您可以编写这样的处理程序,该处理程序将数据解码为“cp1252”,并在utf-8中继续对字符串的其余部分进行解码。
在我的utf-8终端中,我可以构建这样一个混合的错误字符串:
我在这里编写了上述回调函数,并发现了一个捕获:即使您将要解码字符串的位置增加1,以便它将从下一个chratcer开始,如果下一个字符也不是utf-8并且超出范围(128),则在第一个超出范围(128)字符处引发错误-这意味着,如果找到连续的非ascii、非utf-8字符。
解决方法是在error_处理程序中有一个状态变量,它检测到这个“后退”并从最后一次调用它时继续解码-在这个简短的例子中,我将它实现为一个全局变量(在每次调用解码器之前,它必须手动重置为“-1”):
在控制台上:
多亏了jsbueno和其他Google搜索,还有其他的重击,我这样解决了这个问题。
此版本允许有限的机会修复无效字符。未知字符将替换为安全值。
基本上我想把它变成utf8。对于任何失败的字符,我只需将其转换为十六进制,这样我就可以在自己的表中显示或查找它。
这不好看,但我能理解混乱的数据
相关问题 更多 >
编程相关推荐