无法使用python解析简单的json

时间:2013-02-03 15:29:28

标签: python json simplejson

我有一个非常简单的json我无法用simplejson模块解析。 再现:

import simplejson as json
json.loads(r'{"translatedatt1":"Vari\351es"}')

结果:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/pymodules/python2.5/simplejson/__init__.py", line 307, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/pymodules/python2.5/simplejson/decoder.py", line 335, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/pymodules/python2.5/simplejson/decoder.py", line 351, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Invalid \escape: line 1 column 23 (char 23)

任何人都知道错误以及如何正确解析json?

在那里编码的字符串是:Variées

P.S。我使用python 2.5

非常感谢!

2 个答案:

答案 0 :(得分:8)

那是完全正确的; Vari\351es包含无效的转义符,JSON标准不允许\后跟数字。

无论生成什么代码都应该修复。如果这是不可能的,您将需要使用正则表达式来删除这些转义,或者用有效的转义替换它们。

如果我们将351数字解释为八进制数,那将指向unicode代码点U + 00E9,é字符(LATIN SMALL LETTER E WITH ACUTE)。您可以使用以下命令“修复”您的JSON输入:

import re

invalid_escape = re.compile(r'\\[0-7]{1,6}')  # up to 6 digits for codepoints up to FFFF

def replace_with_codepoint(match):
    return unichr(int(match.group(0)[1:], 8))


def repair(brokenjson):
    return invalid_escape.sub(replace_with_codepoint, brokenjson)

使用repair()可以加载您的示例:

>>> json.loads(repair(r'{"translatedatt1":"Vari\351es"}'))
{u'translatedatt1': u'Vari\xe9es'}

您可能需要调整代码点的解释;我选择八进制(因为Variées是一个实际的单词),但是你需要用其他代码点来测试它。

答案 1 :(得分:4)

您可能不打算使用原始字符串,而是使用unicode字符串?

>>> import simplejson as json
>>> json.loads(u'{"translatedatt1":"Vari\351es"}')
{u'translatedatt1': u'Vari\xe9es'}

如果要引用JSON字符串中的数据,则需要使用\uNNNN

>>> json.loads(r'{"translatedatt1":"Vari\u351es"}')
{'translatedatt1': u'Vari\u351es'}

请注意,在这种情况下产生的字典略有不同。解析unicode字符串时,simplejson使用unicode strings作为键。否则,它使用byte string个密钥。

如果您的JSON数据确实使用\351e,那么它只是被破坏而且没有有效的JSON。