Python:json.loads转义时的扼流圈

时间:2009-10-01 17:53:17

标签: python json escaping

我有一个应用程序将一个JSON对象(使用Prototype格式化)发送到ASP服务器。在服务器上,Python 2.6“json”模块尝试加载()JSON,但它在一些反斜杠组合上窒息。观察:

>>> s
'{"FileExists": true, "Version": "4.3.2.1", "Path": "\\\\host\\dir\\file.exe"}'

>>> tmp = json.loads(s)
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  {... blah blah blah...}
  File "C:\Python26\lib\json\decoder.py", line 155, in JSONString
    return scanstring(match.string, match.end(), encoding, strict)
  ValueError: Invalid \escape: line 1 column 58 (char 58)

>>> s[55:60]
u'ost\\d'

所以第58列是转义反斜杠。我以为这个WAS正好逃脱了! UNC是\\host\dir\file.exe,所以我只是用斜线加倍。但显然这并不好。有人可以帮忙吗?作为最后的手段,我正在考虑将\转换为/然后再转回,但这对我来说似乎是一个真正的黑客。

提前致谢!

3 个答案:

答案 0 :(得分:22)

正确的json是:

r'{"FileExists": true, "Version": "4.3.2.1", "Path": "\\\\host\\dir\\file.exe"}'

注意字母r如果省略它,你也需要为Python转义\

>>> import json
>>> d = json.loads(s)
>>> d.keys()
[u'FileExists', u'Path', u'Version']
>>> d.values()
[True, u'\\\\host\\dir\\file.exe', u'4.3.2.1']

注意区别:

>>> repr(d[u'Path'])
"u'\\\\\\\\host\\\\dir\\\\file.exe'"
>>> str(d[u'Path'])
'\\\\host\\dir\\file.exe'
>>> print d[u'Path']
\\host\dir\file.exe

Python REPL默认打印对象repr(obj)的{​​{1}}:

obj

因此,您的原始>>> class A: ... __str__ = lambda self: "str" ... __repr__ = lambda self: "repr" ... >>> A() repr >>> print A() str 字符串未针对JSON正确转义。它包含未转义的s'\d''\f'必须显示print s,否则JSON不正确。

注意:JSON字符串是零个或多个Unicode字符的集合,用双引号括起来,使用反斜杠转义符(json.org)。我在上面的例子中跳过了编码问题(即从字节串到unicode的转换,反之亦然)。

答案 1 :(得分:5)

由于异常为你提供了有问题的转义字符的索引,我开发的这个小黑客可能很好:)

def fix_JSON(json_message=None):
    result = None
    try:        
        result = json.loads(json_message)
    except Exception as e:      
        # Find the offending character index:
        idx_to_replace = int(e.message.split(' ')[-1].replace(')',''))      
        # Remove the offending character:
        json_message = list(json_message)
        json_message[idx_to_replace] = ' '
        new_message = ''.join(json_message)     
        return fix_JSON(json_message=new_message)
    return result

答案 2 :(得分:1)

>>> s
'{"FileExists": true, "Version": "4.3.2.1", "Path": "\\\\host\\dir\\file.exe"}'
>>> print s
{"FileExists": true, "Version": "4.3.2.1", "Path": "\\host\dir\file.exe"}

您实际上并未转义该字符串,因此它正在尝试解析无效的转义码,例如\d\f。考虑使用经过良好测试的JSON编码器,例如json2.js