JSONオブジェクト(プロトタイプでフォーマットされた)をASPサーバーに送信しているアプリケーションがあります。サーバー上で、Python 2.6 "json"モジュールが試行しますJSONをloads()しますが、バックスラッシュの組み合わせで窒息します。
>>> 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
なので、スラッシュを2倍にしました。しかし、どうやらこれは良くありません。誰かが助けることができますか?最後の手段として、\を/に変換してから再び戻すことを検討していますが、これは私にとっては本当のハックのようです。
前もって感謝します!
正しい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)
を出力します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文字列は、バックスラッシュエスケープ( json.org )を使用して、二重引用符で囲まれた0個以上のUnicode文字のコレクションです。上記の例では、エンコーディングの問題(つまり、バイト文字列からユニコードへの変換、およびその逆の変換)をスキップしました。
例外は問題のあるエスケープ文字のインデックスを提供するので、私が開発したこの小さなハックは素晴らしいかもしれません:)
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
>>> 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
などの無効なエスケープコードを解析しようとしています。 json2.js などの十分にテストされたJSONエンコーダーの使用を検討してください。