Python跳过/删除不可解码的字符

时间:2014-06-03 18:38:10

标签: python json unicode

我目前正在将一些客户输入的字符串转换为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)

我无法控制数据的来源,所以我无法提前预防。所以,既然这个坏数据已经存在,我只想用一些占位符替换未知/坏字符,或者删除它们。我怎么能这样做?

2 个答案:

答案 0 :(得分:3)

  

{' FIRST_NAME':' sdffg \ xed',' LAST_NAME':' sdfsadf'}

是一个Python字典,其键和值是字节字符串。这不能用JSON表示,因为JSON没有任何字节概念。 JSON字符串值始终是Unicode,因此要忠实地再现Python字典,您必须确保所有文本键和值都是unicodeu'...')字符串。

Python将让你逃脱'FIRST_NAME',因为它仅限于纯ASCII;最流行的字节编码是ASCII超集,因此Python可以合理安全地隐式地将字符串解码为ASCII。但对于字节超出0x00-0x7F范围的字符串,情况并非如此,例如'sdffg\xed'。在将字符放入字典之前,您应该.decode字节strunicode字符串。 (实际上,您应该尝试确保您的文本数据保存在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')可能是您要查找的编码。

答案 1 :(得分:1)

json.dumps尝试将块转换为ascii(除非您提供编码)。因此,您需要确保您的字符串将编码为ascii。幸运的是,如果未指定编码,unicode()会将其字符串编码为ASCII。所以...

copy = {}
for k, v in d.items():
    copy[k] = unicode(v, errors='ignore')

json.dumps(copy)