2013-02-03 78 views
3

我有一个非常简单的json,我无法用simplejson模块解析。 繁殖:无法用python解析简单的json

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

非常感谢!

回答

8

这将是非常正确的; Vari\351es包含无效转义,JSON标准不允许\后跟数字。

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

如果我们将351数字解释为八进制数,那么它将指向unicode代码点U + 00E9,即é字符(拉丁文小号字母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是一个真正的单词),但是您需要使用其他代码点进行更多测试。

+0

此代码是由Venda平台生产的。不幸的是,我无法改变这种行为。 顺便说一句 - 什么将是一个有效的逃生者? – diemacht

+0

@diemacht:看我的更新。 –

+0

谢谢,但结果不是什么应该是: rapair函数后,我们得到“Varişes”,而它应该是“Variées” – diemacht

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。

+0

我可以这样做,如果字符串是在一些变量,例如: s = r'{“translatedatt1”:“Vari \ 351es”}'?谢谢!!! – diemacht

+0

只是不要以这种方式创建字符串。如果你想创建一个包含unicode数据的字符串,可以去掉'r'前缀并使用'u'。如果你真的想在JSON数据中使用引号,你需要使用'\ u351e'。 – bikeshedder

+0

@bikeshedder:我认为OP意味着*服务器*发送了这些数据。 'r'''可以更容易地向我们显示发送的原始数据。是的,这是破碎的JSON数据... –