如您所知,如果您尝试将此字符串解码为utf-8,则会收到“ UnipreDepre”错误,因为这些伪造的cp1252字符是无效的utf-8-
但是,Python编解码器允许您使用precs.register_error函数注册用于处理编码/解码错误的回调-它获取UnipreDepreerror
aa参数-您可以编写这样的处理程序,以免将数据解码为“ cp1252”,并且继续在utf-8中对字符串的其余部分进行解码。
在我的utf-8终端中,我可以像这样构建一个混合的错误字符串:
>>> a = u"maçã ".enpre("utf-8") + u"maçã ".enpre("cp1252")>>> print amaçã ma�� >>> a.depre("utf-8")Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.6/encodings/utf_8.py", line 16, in depre return precs.utf_8_depre(input, errors, True)UnipreDepreError: 'utf8' prec can't depre bytes in position 9-11: invalid data
我在这里编写了上述回调函数,并发现了一个问题:即使将下一个字符串解码的位置增加1,这样,如果下一个字符也不是utf-8并从下一个字符开始,它将在下一个字符开始如果是range(128)的字符,则会在超出range(128)字符的第一个字符处引发错误-
这意味着,如果找到连续的非ascii,非utf-8字符,则解码将“返回”。
解决此问题的方法是在error_handler中具有状态变量,该状态变量将检测到此“向后移动”并从上次调用它恢复解码-
在这个简短的示例中,我将其实现为全局变量-(必须手动进行在每次调用解码器之前重置为“ -1”):
import precslast_position = -1def mixed_deprer(unipre_error): global last_position string = unipre_error[1] position = unipre_error.start if position <= last_position: position = last_position + 1 last_position = position new_char = string[position].depre("cp1252") #new_char = u"_" return new_char, position + 1precs.register_error("mixed", mixed_deprer)
在控制台上:
>>> a = u"maçã ".enpre("utf-8") + u"maçã ".enpre("cp1252")>>> last_position = -1>>> print a.depre("utf-8", "mixed")maçã maçã
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)