Python 如何解码字节(使用ASCII)而不丢失任何;“垃圾”;如果xmlcharrefresplace和反斜杠替换don';不行?
我有一个网络资源,它返回的数据(根据规范)应该是ASCII编码的字符串。但在少数情况下,我会得到垃圾数据 例如,一个资源返回Python 如何解码字节(使用ASCII)而不丢失任何;“垃圾”;如果xmlcharrefresplace和反斜杠替换don';不行?,python,python-3.x,encoding,byte,Python,Python 3.x,Encoding,Byte,我有一个网络资源,它返回的数据(根据规范)应该是ASCII编码的字符串。但在少数情况下,我会得到垃圾数据 例如,一个资源返回b'\xd3PS-90AC',而另一个资源返回b'PS-90AC' 第一个值包含非ASCII字符串。显然违反了规范,但不幸的是这超出了我的控制范围。我们中没有人100%确定这真的是垃圾或应该保留的数据 调用远程资源的应用程序将数据保存在本地数据库中以供日常使用。我可以简单地做一个数据解码('ascii','replace')或..'ignore'),但这样我就会丢失数据,而
b'\xd3PS-90AC'
,而另一个资源返回b'PS-90AC'
第一个值包含非ASCII字符串。显然违反了规范,但不幸的是这超出了我的控制范围。我们中没有人100%确定这真的是垃圾或应该保留的数据
调用远程资源的应用程序将数据保存在本地数据库中以供日常使用。我可以简单地做一个数据解码('ascii','replace')
或..'ignore')
,但这样我就会丢失数据,而这些数据以后可能会很有用
我的直接反应是使用'xmlcharrefreplace'
或'backslaschreplace'
作为错误处理程序。只是因为它会产生一个可显示的字符串。但是我得到了以下错误:TypeError:不知道如何处理错误回调中的UnicodeDecodeError
唯一有效的错误处理程序是subscrateescape
,但这似乎是针对文件名的。另一方面,就我的意图和目的而言,它会起作用
为什么'xmlcharrefreplace'
和'backslashreplace'
不起作用?我不明白这个错误
例如,预期的执行将是:
>>> data = b'\xd3PS-90AC'
>>> new_data = data.decode('ascii', 'xmlcharrefreplace')
>>> print(repr(new_data))
'&#d3;PS-90AC'
这是一个人为的例子。我的目标是不丢失任何数据。如果我使用ignore
或replace
错误处理程序,所涉及的字节将基本上消失,信息也将丢失
>>> data = b'\xd3PS-90AC'
>>> data.decode('ascii', 'surrogateescape')
'\udcd3PS-90AC'
它不使用html实体,但这是一个不错的起点。如果不够,您将不得不使用我的假设注册您自己的错误处理程序
对于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')
对于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')
两者都产生:
'ÓPS-90AC'
为了完整起见,我想补充一下,从Python3.5开始,
backslashreplace
用于解码,因此您不再需要添加自定义错误处理程序。我不清楚预期的“输出”是什么。您想将“ASCII”字符串和“垃圾”字节放在一起(比如u'\u00d3PS-90AC'
)?或者类似于data.decode('unicode_escape')
的结果?我添加了一些示例执行。并不是说示例输出有点来自我的头顶。如果它使用不同的语法,那没关系。我添加了标记Python3,因为您的示例暗示了这一点。还是我错了?这很好;)asSubrogateScape
和backslashreplace
仅存在于Python3中。目前,我正在编写的库仍被一个Python2应用程序使用,因此首选Python2解决方案,但我们计划最终将剩下的一个应用程序移植到Python3。所以没关系。。。最糟糕的情况是,我们现在就得把它移植过来:)我一直在读这个话题。我不确定我最初使用xmlcharrefreplace
的想法是否是个好主意。引用的值指向“Unicode代码点”。通过查找211
,我找到了ȑ
(utf-8字节值C891
)。因此,我不确定您将如何从211
返回到\xd3
。我认为使用subrogateScape
可能不会那么模棱两可\也许我们过于关注“如何”而不真正知道你想做什么。是时候问另一个问题了:)?@exhuma BTW211
(10)是d3
(16)。这只不过是一个简单的dec->hex转换。话虽如此,我个人会推动使用Unicode代码点。但是一旦angin没有澄清你对“瘾君子字符串”的用法,就很难说了。你是对的。我想过去两天我看字节太多了。我可能应该休息一下。