2013-02-03 2 views
3

나는 simplejson 모듈로 파싱 할 수없는 매우 간단한 json을 가지고있다. 복제 :파이썬으로 간단한 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. 파이썬 2.5를 사용합니다.

고마워요!

답변

8

매우 정확합니다. Vari\351es에 유효하지 않은 이스케이프가 포함 된 경우 JSON 표준은 \ 다음에 숫자 만 허용합니다.

코드를 수정해야하는 것은 무엇이든지 제작해야합니다. 이것이 불가능할 경우 정규식을 사용하여 이스케이프를 제거하거나 유효한 이스케이프로 대체해야합니다.

351 숫자를 8 진수로 해석하면 유니 코드 코드 포인트 U + 00E9, é 문자 (LATIN SMALL LETTER E WITH ACUTE)를 가리 킵니다.

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 입력이 '수리'할 수

>>> json.loads(repair(r'{"translatedatt1":"Vari\351es"}')) 
{u'translatedatt1': u'Vari\xe9es'} 

당신은 코드 포인트의 해석을 조정해야 할 수도 있습니다; 8 진수를 선택합니다 (Variées이 실제 단어이기 때문에). 그러나 다른 코드 포인트와 함께 더 많이 테스트해야합니다.

+0

이 코드는/Venda 플랫폼에 의해 생산되었습니다.불행히도, 나는이 행동을 바꿀 수 없다. BTW - 유효한 도망자는 무엇입니까? – diemacht

+0

@diemacht : 내 업데이트를 참조하십시오. –

+0

감사합니다. 결과는 다음과 같을 수 없습니다 : rapair 기능을 수행 한 후 "VariESES"가 표시되고 "Variées"이어야합니다 – diemacht

4

아마도 원시 문자열을 사용하지 않고 유니 코드 문자열을 사용하려고했을 것입니까? 당신은 JSON 문자열 내부의 데이터를 인용하려면

>>> import simplejson as json 
>>> json.loads(u'{"translatedatt1":"Vari\351es"}') 
{u'translatedatt1': u'Vari\xe9es'} 

당신은 \uNNNN를 사용해야합니다 :

>>> json.loads(r'{"translatedatt1":"Vari\u351es"}') 
{'translatedatt1': u'Vari\u351es'} 

이 결과 DICT이 경우에 약간 차이가 있습니다. 유니 코드 문자열을 구문 분석 할 때 simplejson은 unicode strings 키를 사용합니다. 그렇지 않으면 byte string 키를 사용합니다.

실제로 JSON 데이터가 \351e을 사용하는 경우 단순히 깨진 것보다 유효한 JSON이 아닙니다.

+0

문자열이 어떤 변수에 있으면 어떻게 할 수 있습니까? 예 : s = r '{ "translatedatt1": "Vari \ 351es"}'? 감사!!! – diemacht

+0

그런 식으로 문자열을 작성하지 마십시오. 유니 코드 데이터를 포함하는 문자열을 만들려면'r' 접두사를 없애고 대신에'u'를 사용하십시오. JSON 데이터 내에서 인용 부호를 사용하려면'\ u351e'를 사용해야합니다. – bikeshedder

+0

@bikeshedder : OP는 * 서버가 해당 데이터를 보냈다는 의미입니다. 'r' '을 사용하면 전송 된 원시 데이터를보다 쉽게 ​​표시 할 수 있습니다. 예, JSON 데이터가 깨졌습니다. –