Python: json.loads 函数处理转义字符时出错
我有一个应用程序,它把一个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列是转义的反斜杠。我以为这个转义是正确的!UNC路径是\\host\dir\file.exe
,所以我只是把斜杠加倍了。但是显然这样不行。有人能帮忙吗?作为最后的办法,我在考虑把反斜杠转换成斜杠,然后再转换回来,但我觉得这真的是个临时的解决办法。
提前谢谢大家!
3 个回答
0
>>> 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。
20
因为这个错误提示会告诉你出错的转义字符的位置,所以我开发了一个小技巧,可能会对你有帮助 :)
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(str(e).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
34
正确的 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(交互式解释器)中,默认情况下会打印对象 obj
的 repr(obj)
表示:
>>> class A:
... __str__ = lambda self: "str"
... __repr__ = lambda self: "repr"
...
>>> A()
repr
>>> print A()
str
所以你最开始的 s
字符串在 JSON 格式上是不正确的。它包含了没有转义的 '\d'
和 '\f'
。print s
必须显示 '\\d'
,否则就不是正确的 JSON。
注意:JSON 字符串是一组零个或多个 Unicode 字符,用双引号包裹,并使用反斜杠进行转义(json.org)。在上面的例子中,我省略了编码问题(也就是字节字符串和 Unicode 之间的转换)。