我目前正在将一些客户输入的字符串转换为 json 的一部分。我已经用字符串做了一个字典,现在正在做:
json.dumps(some_dict)
问题是,对于一些客户输入的数据,似乎他们以某种方式输入了乱码,并试图转储到 json 破坏了整个事情:
{'FIRST_NAME': 'sdffg\xed', 'LAST_NAME': 'sdfsadf'}
然后让我:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xed in position 6: ordinal not in range(128)
我无法控制数据的来源,因此无法提前阻止。所以,既然这个坏数据已经存在,我正在考虑用一些占位符字符替换未知/坏字符,或者删除它们。我该怎么做?
最佳答案
{'FIRST_NAME': 'sdffg\xed', 'LAST_NAME': 'sdfsadf'}
是一个 Python 字典,其键和值都是字节串。这不能用 JSON 表示,因为 JSON 没有任何字节的概念。 JSON 字符串值始终是 Unicode,因此要忠实地再现 Python 字典,您必须确保所有文本键和值都是 unicode
(u'...'
)字符串。
Python 将允许您使用 'FIRST_NAME'
,因为它仅限于纯 ASCII;最流行的字节编码是 ASCII 超集,因此 Python 可以合理安全地将字符串隐式解码为 ASCII。但对于字节在 0x00-0x7F 范围之外的字符串,情况并非如此,例如 'sdffg\xed'
。在将字节 str
放入字典之前,您应该将其 .decode
为 unicode
字符串。 (实际上,您应该尝试确保在所有应用程序处理中将文本数据保存在 Unicode 字符串中,仅当从非 Unicode 源加载输入并且输出必须转到非 Unicode 目的地时才转换为字节字符串. 所以此时你不应该在字典中得到字节内容。检查输入的来源 - 你可能应该进一步执行 decode()
步骤。)
您可以使用以下方法解码为 Unicode 并跳过或替换非 ASCII 字符:
>>> 'sdffg\xed'.decode('ascii', 'ignore')
u'sdffg'
>>> 'sdffg\xed'.decode('ascii', 'replace')
u'sdffg\uFFFD' # U+FFFD = �. Unicode string, json.dump can serialise OK
但是丢弃可能有用的数据似乎是一种耻辱。如果您可以猜出用于创建字节字符串的编码,则可以保留可恢复的非 ASCII 字符子集。如果字节 0xED 表示字符 U+00ED i-acute (í
),则 .decode('iso-8859-1')
或可能是 .decode ('cp1252')
可能是您正在寻找的编码。
关于Python 跳过/删除不可解码的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24022531/