2013-02-03 100 views
3

我有一個非常簡單的json,我無法用simplejson模塊解析。 繁殖:無法用python解析簡單的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?

所編碼的字符串有:Variées

P.S.我用python 2.5

非常感謝!

回答

8

這將是非常正確的; Vari\351es包含無效轉義,JSON標準不允許\後跟數字。

無論產生的代碼應該修復。如果這是不可能的,你需要使用一個正則表達式來刪除這些轉義,或者用有效的轉義替換它們。

如果我們將351數字解釋爲八進制數,那麼它將指向unicode代碼點U + 00E9,即é字符(拉丁文小號字母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'} 

您可能需要調整碼點的解釋;我選擇八進制(因爲Variées是一個真正的單詞),但是您需要使用其他代碼點進行更多測試。

+0

此代碼是由Venda平臺生產的。不幸的是,我無法改變這種行爲。 順便說一句 - 什麼將是一個有效的逃生者? – diemacht

+0

@diemacht:看我的更新。 –

+0

謝謝,但結果不是什麼應該是: rapair函數後,我們得到「Varişes」,而它應該是「Variées」 – diemacht

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

請注意,所產生的字典在這種情況下略有不同。解析unicode字符串時,simplejson使用unicode strings作爲鍵。否則它使用byte string鍵。

如果您的JSON數據實際上使用\351e而不是簡單地打破並且沒有有效的JSON。

+0

我可以這樣做,如果字符串是在一些變量,例如: s = r'{「translatedatt1」:「Vari \ 351es」}'?謝謝!!! – diemacht

+0

只是不要以這種方式創建字符串。如果你想創建一個包含unicode數據的字符串,可以去掉'r'前綴並使用'u'。如果你真的想在JSON數據中使用引號,你需要使用'\ u351e'。 – bikeshedder

+0

@bikeshedder:我認爲OP意味着*服務器*發送了這些數據。 'r'''可以更容易地向我們顯示發送的原始數據。是的,這是破碎的JSON數據... –