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

时间:2021-11-07 03:10:52

I have an application that is sending a JSON object (formatted with Prototype) to an ASP server. On the server, the Python 2.6 "json" module tries to loads() the JSON, but it's choking on some combination of backslashes. Observe:

我有一个应用程序将一个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'

So column 58 is the escaped-backslash. I thought this WAS properly escaped! UNC is \\host\dir\file.exe, so I just doubled up on slashes. But apparently this is no good. Can someone assist? As a last resort I'm considering converting the \ to / and then back again, but this seems like a real hack to me.

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

Thanks in advance!

提前致谢!

3 个解决方案

#1


17  

The correct json is:

正确的json是:

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

Note the letter r if you omit it you need to escape \ for Python too.

注意字母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']

Note the difference:

注意区别:

>>> 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 prints by default the repr(obj) for an object obj:

Python REPL默认打印对象obj的repr(obj):

>>> class A:
...   __str__ = lambda self: "str"
...   __repr__  = lambda self: "repr"
... 
>>> A()
repr
>>> print A()
str

Therefore your original s string is not properly escaped for JSON. It contains unescaped '\d' and '\f'. print s must show '\\d' otherwise it is not correct JSON.

因此,对于JSON,您的原始字符串未正确转义。它包含未转义的'\ d'和'\ f'。 print必须显示'\\ d',否则JSON不正确。

NOTE: JSON string is a collection of zero or more Unicode characters, wrapped in double quotes, using backslash escapes (json.org). I've skipped encoding issues (namely, transformation from byte strings to unicode and vice versa) in the above examples.

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

#2


3  

Since the exception gives you the index of the offending escape character, this little hack I developed might be nice :)

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

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

#3


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"}

You've not actually escaped the string, so it's trying to parse invalid escape codes like \d or \f. Consider using a well-tested JSON encoder, such as json2.js.

你实际上没有转义字符串,所以它试图解析无效的转义码,如\ d或\ f。考虑使用经过良好测试的JSON编码器,例如json2.js。

#1


17  

The correct json is:

正确的json是:

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

Note the letter r if you omit it you need to escape \ for Python too.

注意字母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']

Note the difference:

注意区别:

>>> 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 prints by default the repr(obj) for an object obj:

Python REPL默认打印对象obj的repr(obj):

>>> class A:
...   __str__ = lambda self: "str"
...   __repr__  = lambda self: "repr"
... 
>>> A()
repr
>>> print A()
str

Therefore your original s string is not properly escaped for JSON. It contains unescaped '\d' and '\f'. print s must show '\\d' otherwise it is not correct JSON.

因此,对于JSON,您的原始字符串未正确转义。它包含未转义的'\ d'和'\ f'。 print必须显示'\\ d',否则JSON不正确。

NOTE: JSON string is a collection of zero or more Unicode characters, wrapped in double quotes, using backslash escapes (json.org). I've skipped encoding issues (namely, transformation from byte strings to unicode and vice versa) in the above examples.

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

#2


3  

Since the exception gives you the index of the offending escape character, this little hack I developed might be nice :)

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

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

#3


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"}

You've not actually escaped the string, so it's trying to parse invalid escape codes like \d or \f. Consider using a well-tested JSON encoder, such as json2.js.

你实际上没有转义字符串,所以它试图解析无效的转义码,如\ d或\ f。考虑使用经过良好测试的JSON编码器,例如json2.js。