2009-10-01 9 views
11

पर चुटकुले करता है मेरे पास एक ऐसा एप्लिकेशन है जो एक एएसपी सर्वर पर JSON ऑब्जेक्ट (प्रोटोटाइप के साथ स्वरूपित) भेज रहा है। सर्वर पर, पायथन 2.6 "जेसन" मॉड्यूल जेएसओएन लोड करने की कोशिश करता है, लेकिन यह बैकस्लाश के कुछ संयोजन पर चकित है। निरीक्षण करें:पायथन: json.loads escapes

>>> 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 बच निकला हुआ बैकस्लैश है। मैंने सोचा कि यह ठीक से बच निकला था! यूएनसी \\host\dir\file.exe है, इसलिए मैं सिर्फ स्लेश पर दोगुना हो गया। लेकिन जाहिर है यह कोई अच्छा नहीं है। क्या कोई सहायता कर सकता है? आखिरी उपाय के रूप में मैं \ n/और फिर फिर से परिवर्तित करने पर विचार कर रहा हूं, लेकिन यह मेरे लिए असली हैक जैसा लगता है।

अग्रिम धन्यवाद!

उत्तर

16

सही json है:

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

नोट पत्र r यदि आप इसे छोड़ देते हैं आप भी अजगर के लिए \ से बचने के लिए की जरूरत है।

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

नोट अंतर: एक वस्तु obj के लिए डिफ़ॉल्ट repr(obj) द्वारा

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

अजगर आरईपीएल प्रिंट:

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

:) >>> एस = आर '{ "fileexists" हो सकता है: सच , "संस्करण": "4.3.2.1", "पथ": "\\\\ मेजबान \\ dir \\ file.exe"} ' >>> json.loads (0) {u'FileExists' : सच है, u'Path ': u' \\\\ होस्ट \\ dir \\ file.exe ', u'Version': u'4.3.2.1 '} – Chris

+0

तो वास्तव में क्या कर रहा है? मैं इसे एक स्ट्रिंग पर कैसे लागू कर सकता हूं जो पहले से ही संग्रहीत है, कहें, "foo"। क्या यह किसी प्रकार का एन्कोडिंग है? – Chris

+0

''s =' 'प्रारूपण तोड़ता है। – jfs

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

आप वास्तव में स्ट्रिंग से छोड़ा नहीं गया है, इसलिए यह \d या \f तरह अवैध मुक्ति कोड पार्स करने के लिए कोशिश कर रहा है। json2.js जैसे एक अच्छी तरह से परीक्षण किए गए JSON एन्कोडर का उपयोग करने पर विचार करें।

2

के बाद से अपवाद आप हमलावर भागने चरित्र के सूचकांक देता है, इस छोटे से हैक मैं विकसित अच्छा :)

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 
+1

कोड के लिए धन्यवाद। मेरे मामले में (पायथन 3.5) मुझे 'idx_to_replace = int (e.message.split ('') [- 1] .replace (')', '' ') बदलने के लिए आवश्यक था)' 'idx_to_replace = int (str (ई) .split ('') [- 1]। स्थान (')', '')) ' – TitanFighter

संबंधित मुद्दे