2011-02-03 16 views
9

का उपयोग कर अनजान कुंजी के साथ अमान्य JSON को पार्स करने के लिए मुझे रूबी में कुछ अमान्य JSON को पार्स करने की आवश्यकता है।ActiveSupport 3 (रेल)

कुछ की तरह:

json_str = '{name:"Javier"}' 
ActiveSupport::JSON.decode json_str 

आप देख सकते हैं, यह अवैध है क्योंकि हैश कुंजी उद्धृत नहीं है, यह

json_str = '{"name":"Javier"}' 

होना चाहिए लेकिन वह बदला नहीं जा सकता है और मैं करने के लिए है कुंजियों को अनदेखा करें।

मैं इसे ActiveSupport 2.x से पार्स कर सकता हूं, लेकिन ActiveSupport 3 मुझे अनुमति नहीं देता है। यह मुझे फेंकता है:

Yajl::ParseError: lexical error: invalid string in json text. 
             {name:"Javier"} 
        (right here) ------^ 

वैसे, यह कुछ रेल पुस्तकालयों का उपयोग कर एक रूबी आवेदन है, लेकिन यह एक रेल आवेदन

अग्रिम धन्यवाद नहीं है

+0

यह अवैध जेसन कहां से आ रहा है? एक आराम एपीआई या कुछ फाइल? वास्तव में जेसन को ठीक करना सबसे अच्छा होगा, एक पार्सर जो अमान्य जेसन स्वीकार करता है बुरा है और मुझे खुशी है कि वे अब यजल का उपयोग कर रहे हैं। –

+0

हां यह एक एपीआई है। और हाँ यह बदबू आ रही है कि मुझे इसके लिए एक कामकाज करना है लेकिन मेरे पास एपीआई के डेवलपर्स के साथ कोई संपर्क नहीं है। –

उत्तर

0

कुछ इस तरह?

require 'json' 
json_str = '{name:"Javier"}' 
hash = JSON::parse(json_str.gsub(/{|:"/, {'{'=>'{"', ':"'=>'":"'})) 
+0

वाह मैंने सोचा कि मैं JSON को पूर्व-विश्लेषण किए बिना ठीक कर सकता हूं (शायद किसी प्रकार का ActiveSupport ध्वज सक्रिय कर रहा हूं)। मैं उस कोड पर नज़र डालने जा रहा हूं और आपको बताता हूं कि यह मेरे लिए कैसे काम करता है। –

+0

क्षमा करें, यह मुझे एक सिंटेक्स त्रुटि अपवाद उठाया: 'अवैध नियमित अभिव्यक्ति; कोई पिछला पैटर्न नहीं है, जिसके लिए '{' कार्डिनलिटी को 1:/{|: "/' पर परिभाषित करेगा –

2

मैं इस अमान्य JSON ठीक करने के लिए रेगुलर एक्सप्रेशन का उपयोग होगा:

json_str = '{name:"Javier"}' 
json_str.gsub!(/(['"])?([a-zA-Z0-9_]+)(['"])?:/, '"\2":') 
hash = Yajl::Parser.parse(json_str) 
0

यहाँ कुछ हद तक एक मजबूत regex आप उपयोग कर सकते है। यह सही नहीं है - विशेष रूप से यह कुछ कोने मामलों में जहां मूल्यों खुद को json की तरह पाठ हो में काम नहीं करता, लेकिन यह सबसे सामान्य मामलों में काम करेगा:

quoted_json = unquoted_json.gsub(/([{,]\s*)(\w+)(\s*:\s*["\d])/, '\1"\2"\3') 

सबसे पहले इसके लिए लग रहा है या तो एक { या , जो कुंजी नाम से पहले के चरित्र के विकल्प हैं (\s* के साथ व्हाइटस्पेस की किसी भी मात्रा को भी अनुमति देता है)।

(\w+) 

:

([{,]\s*) 

तो यह कुंजी ही है, जो अक्षर, अंक, और अंडरस्कोर से बना है (जो आसानी से regex के लिए एक \w चरित्र वर्ग की आपूर्ति) कब्जा: यह एक समूह के रूप में यह कब्जा आखिरकार, यह एक महत्वपूर्ण नाम का पालन करने के लिए मेल खाता है; यानी एक कॉलन या तो एक प्रारंभ उद्धरण (एक स्ट्रिंग मान के लिए) या एक अंक (एक संख्यात्मक मूल्य के लिए) के बाद। इसके अलावा अतिरिक्त व्हाइट की अनुमति देता है, और एक समूह में पूरी बात को दर्शाता:

(\s*:\s*["\d]) 

प्रत्येक मैच के लिए, यह सिर्फ तीन टुकड़े वापस एक साथ रखता है, लेकिन कुंजी के आसपास उद्धरण के साथ (लगभग कब्जा समूह # 2 उद्धरण तो):

'\1"\2"\3' 
संबंधित मुद्दे