3

simplejson モジュールでは解析できない非常に単純な 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を正しく解析する方法を知っている人はいますか?

そこにエンコードされている文字列は次のとおりです。

PS私はpython 2.5を使用しています

どうもありがとう!

4

2 に答える 2

8

それはまったく正しいでしょう。に無効なエスケープが含まれている場合、JSON 標準では、数字だけが続くVari\351esことは許可されていません。\

そのコードを生成したものは何でも修正する必要があります。それが不可能な場合は、正規表現を使用してこれらのエスケープを削除するか、有効なエスケープに置き換える必要があります。

数値を 8 進数として解釈する351と、Unicode コード ポイント U+00E9、é文字 (LATIN SMALL LETTER 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'}

コードポイントの解釈を調整する必要がある場合があります。私は 8 進数を選択しましたが (Variéesは実際の単語であるため)、他のコードポイントでこれをさらにテストする必要があります。

于 2013-02-03T15:34:20.520 に答える
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'}

この場合、結果の辞書はわずかに異なることに注意してください。simplejsonunicode stringsがキーに使用する Unicode 文字列を解析する場合。それ以外の場合はbyte stringキーを使用します。

JSONデータが実際に使用されている場合\351e、それは単に壊れており、有効なJSONではありません.

于 2013-02-03T15:34:05.417 に答える