如果 xmlcharrefreplace 和 backslashreplace 不起作用,我应该如何解码字节(使用 ASCII)而不丢失任何“垃圾”字节?

exh*_*uma 5 python encoding byte python-3.x

我有一个网络资源,它返回给我的数据(根据规范)应该是 ASCII 编码的字符串。但在极少数情况下,我会收到垃圾数据。

例如,一个资源返回b'\xd3PS-90AC',而另一个资源对于相同的键返回b'PS-90AC'

第一个值包含非 ASCII 字符串。显然违反了规范,但不幸的是这超出了我的控制范围。我们没有人 100% 确定这确实垃圾或应该保留的数据。

调用远程资源的应用程序将数据保存在本地数据库中以供日常使用。我可以简单地执行“data.decode('ascii', 'replace')或”操作..., 'ignore'),但随后我会丢失稍后可能有用的数据。

我的第一反应是使用'xmlcharrefreplace'or'backslashreplace'作为错误处理程序。很简单,因为它会产生一个可显示的字符串。但后来我收到以下错误:TypeError: don't know how to handle UnicodeDecodeError in error callback

唯一有效的错误处理程序是surrogateescape,但这似乎适用于文件名。另一方面,对于我的意图和目的来说,它会起作用。

为什么有效'xmlcharrefreplace''backslashreplace'无效?我不明白这个错误。

例如预期执行将是:

>>> data = b'\xd3PS-90AC'
>>> new_data = data.decode('ascii', 'xmlcharrefreplace')
>>> print(repr(new_data))
'&#d3;PS-90AC'
Run Code Online (Sandbox Code Playgroud)

这是一个人为的例子。我的目标是不丢失任何数据。如果我使用ignorereplace错误处理程序,则相关字节基本上会消失,并且信息会丢失。

Syl*_*oux 2

>>> data = b'\xd3PS-90AC'
>>> data.decode('ascii', 'surrogateescape')
'\udcd3PS-90AC'
Run Code Online (Sandbox Code Playgroud)

它不使用html 实体,但它是一个不错的起点。如果还不够,您将必须使用我假设的codecs.register_error注册自己的错误处理程序。

对于Python3:

def handler(err):
    start = err.start
    end = err.end
    return ("".join(["&#{0};".format(err.object[i]) for i in range(start,end)]),end)

import codecs
codecs.register_error('xmlcharreffallback', handler)
data = b'\xd3PS-90AC'
data.decode('ascii', 'xmlcharreffallback')
Run Code Online (Sandbox Code Playgroud)

对于Python 2

def handler(err):
    start = err.start
    end = err.end
    return (u"".join([u"&#{0};".format(ord(err.object[i])) for i in range(start,end)]),end)

import codecs
codecs.register_error('xmlcharreffallback', handler)
data = b'\xd3PS-90AC'
data.decode('ascii', 'xmlcharreffallback')
Run Code Online (Sandbox Code Playgroud)

两者都生产:

'ÓPS-90AC'
Run Code Online (Sandbox Code Playgroud)