गुणों पर उद्धरण के बिना JSON.stringify?


95

मैं एक ऐसी सेवा का उपयोग कर रहा हूं जो गलत JSON प्रारूप (गुणों के आसपास कोई दोहरे उद्धरण नहीं) का उपयोग कर रही है। इसलिए मुझे भेजने की आवश्यकता है

{ name: "John Smith" } के बजाय { "name": "John Smith" }

इस प्रारूप को नहीं बदला जा सकता क्योंकि यह मेरी सेवा नहीं है।

किसी को ऊपर की तरह एक जावास्क्रिप्ट वस्तु प्रारूप करने के लिए एक कठोर मार्ग का पता है?

जवाबों:


115

यह सरल नियमित अभिव्यक्ति समाधान ज्यादातर मामलों में JSON संपत्ति के नामों को रद्द करने के लिए काम करता है:

const object = { name: 'John Smith' };
const json = JSON.stringify(object);  // {"name":"John Smith"}
console.log(json);
const unquoted = json.replace(/"([^"]+)":/g, '$1:');
console.log(unquoted);  // {name:"John Smith"}

चरम परिस्थिति में:

var json = '{ "name": "J\\":ohn Smith" }'
json.replace(/\\"/g,"\uFFFF");  // U+ FFFF
json = json.replace(/"([^"]+)":/g, '$1:').replace(/\uFFFF/g, '\\\"');
// '{ name: "J\":ohn Smith" }'

इसे ठीक करने के लिए रोब डब्ल्यू का विशेष धन्यवाद।

सीमाएं

सामान्य मामलों में पूर्वोक्त regexp काम करेगा, लेकिन गणितीय रूप से JSON प्रारूप को एक नियमित अभिव्यक्ति के साथ वर्णन करना असंभव है, जैसे कि यह हर एक मामले में काम करेगा (समान संख्या में घुंघराले ब्रैकेट की गिनती करना rexxp के साथ असंभव है।) इसलिए, मेरे पास है। मूल फ़ंक्शन के माध्यम से JSON स्ट्रिंग को औपचारिक रूप से पार्स करके उद्धरण को निकालने के लिए एक नया फ़ंक्शन बनाएं और इसे पुन: व्यवस्थित करें:

function stringify(obj_from_json) {
    if (typeof obj_from_json !== "object" || Array.isArray(obj_from_json)){
        // not an object, stringify using native function
        return JSON.stringify(obj_from_json);
    }
    // Implements recursive object serialization according to JSON spec
    // but without quotes around the keys.
    let props = Object
        .keys(obj_from_json)
        .map(key => `${key}:${stringify(obj_from_json[key])}`)
        .join(",");
    return `{${props}}`;
}

उदाहरण: https://jsfiddle.net/DerekL/mssybp3k/


3
-1 मुझे भी नहीं था, लेकिन आपको प्रश्न को ध्यान से पढ़ना चाहिए। ओपी को (टूटे हुए) जोंस को ऑब्जेक्ट को एनकोड करना है, न कि पार्स / मूल्यांकन करना।
सलमान ए

7
@ डेरेक यह विधि विश्वसनीय नहीं है । उदाहरण के लिए, यह इनपुट लें: {"foo":"e\":bar"}(वैध JSON) बन जाता है {foo:e:bar"}(...)!
रॉब डब्ल्यू

1
@ डेरेक /\\\"/को सरल बनाया जा सकता है /\\"/। वैश्विक ध्वज जोड़ने के लिए मत भूलना /\\"/g, या यह कई के साथ तार पर टूट जाएगा \"। बेतरतीब चरित्र के लिए, संपादक के चुटकुले के मामले में कभी भी शाब्दिक U + FFFF का उपयोग करें, लेकिन एक भागने का क्रम। Reverting के लिए regex बन जाएगा /\uFFFF/g
रोब डब्ल्यू

2
@ डेरेक 會 朕 ere आपके रेगेक्स /\"([^(\")"]+)\":/gको सरल बनाया जा सकता है /"([^"]+)":/g, regex101.com/r/qnz0ld/2
tanguy_k

1
@endriu उस मामले में केवल शून्य मानों के लिए एक अतिरिक्त जाँच जोड़ें।
डेरेक 會 會

18

ऐसा लगता है कि यह एक सरल वस्तु है, जिसे आप देख रहे हैं।

Node.js में इसका उपयोग ऑब्जेक्ट ऑब्जेक्ट और कॉलिंग use.inspect (yourObject) द्वारा किया जाता है। यह आपको वह सब देगा जो आप चाहते हैं। विधि के आवेदन की गहराई सहित अधिक विकल्पों के लिए इस लिंक का पालन करें। http://nodejs.org/api/util.html#util_util_inspect_object_options

तो, जो आप खोज रहे हैं वह मूल रूप से एक वस्तु निरीक्षक है जो जेन्सन कन्वर्टर नहीं है। JSON प्रारूप निर्दिष्ट करता है कि सभी गुणों को दोहरे उद्धरण चिह्नों में संलग्न किया जाना चाहिए। इसलिए JSON कन्वर्टर्स ऐसा नहीं होगा जो आप चाहते हैं कि बस एक JSON फॉर्मेट नहीं है। यहां दिए गए विवरण: https://developer.mozilla.org/en-US/docs/Using_native_JSON

स्ट्रिंग या निरीक्षण का उद्देश्य वह है जो आपको अपने सर्वर की भाषा के आधार पर चाहिए।


1
आपका बहोत धन्य्वाद! यही वह है जिसकी तलाश में मैं हूं। मैं अपने गेम में ws सर्वर पर डेटा उत्सर्जित करने के लिए json का उपयोग करता हूं और विश्वास करता हूं कि संपत्ति के नामों के आसपास अतिरिक्त उद्धरण चिह्नों से निपटने के लिए नहीं होने से डेटा की एक बड़ी मात्रा में बचत होती है! बस स्पष्ट करने के लिए, .toSource()नोडज के भीतर भी ठीक काम करता है, लेकिन सरणियों में वस्तुओं को काम नहीं करता है। utilसरणियों और सरणियों जो अद्भुत है में वस्तुओं के लिए काम करता है का निरीक्षण किया, इसे प्यार करता हूँ।
नीक न्यूमैन

3
util.inspect()सिर्फ एक Neo4j क्वेरी में एक ऑब्जेक्ट लिखते समय मेरे लिए बहुत बढ़िया काम किया, एक ही बार में कई Params सेट करने के लिए।
agm1984

1
नोडज लिंक से:> use.inspect () विधि ऑब्जेक्ट का स्ट्रिंग प्रतिनिधित्व करता है जो डीबगिंग के लिए अभिप्रेत है। Use.inspect का आउटपुट किसी भी समय बदल सकता है और इसे प्रोग्रामेटिक रूप से निर्भर नहीं होना चाहिए।
पीटर रोहलेन

5

आप JSON प्रारूप को परिभाषित करने वाले व्यक्ति द्वारा बनाए गए पार्सर के स्रोत कोड को देख सकते हैं । के लिए देखो फ़ंक्शन कॉल: उन्हें उद्धरण द्वारा एक मूल्य के चारों ओर। कीज़ को 326 और 338 लाइनों पर उद्धृत किया गया है ।json2.js quote

संशोधन के बाद पुस्तकालय को शामिल न करें। इसके बजाय केवल प्रासंगिक ( stringify) भाग लें, या कम से कम JSONकिसी और चीज़ से प्रतिस्थापित करें, जैसे। FAKEJSON

उदाहरण के लिए, एक वस्तु FAKEJSONजो केवल परिभाषित की गई है stringify: http://jsfiddle.net/PYudw/


जब आप इसे शुद्ध जावास्क्रिप्ट में कर सकते हैं तो आपको एक अतिरिक्त पुस्तकालय की आवश्यकता क्यों होगी?
डेरेक 會 會 ere

यह एक अच्छा विचार है। मैं रेपो को कांटा करूँगा, उद्धरणों को हटा दूंगा, और JSON ऑब्जेक्ट का नाम बदलकर FAILJSON जैसे कुछ स्पष्ट कर दूंगा कि आप वास्तविक JSON ऑब्जेक्ट या वास्तविक JSON के साथ काम नहीं कर रहे हैं ।
रिचर्ड टॉवर्स

@ डेरेक पुस्तकालय को पूरे के रूप में शामिल नहीं किया जाना चाहिए। केवल JSON.stringifyभाग लें, और उद्धरण निकालें। चूंकि लाइब्रेरी JSON को परिभाषित करने वाले व्यक्ति द्वारा बनाई गई है , इसलिए हम यह सुनिश्चित कर सकते हैं कि परिणाम बहुत वैध JSON है।
रॉब डब्ल्यू

ऐसा लगता है कि यह सबसे अच्छा तरीका है।
डेरेक 會 會 ere

हाँ, डेरेक से सहमत हैं। यद्यपि उसका प्रतिरूप ठीक काम करता है, मुझे क्रॉफर्ड के कोड के साथ अधिक आत्मविश्वास महसूस होता है, डेरेक को कोई अपमान नहीं होता। .toSource()अच्छा काम करता है, लेकिन इसमें शामिल नहीं है यदि आपकी वस्तु सरणी में है जो कि एक बमर है (और मैं नोड पर हूं तो ब्राउज़र कंपिटर्स एक मुद्दा नहीं है: पी) इसलिए मैं इस विधि का उपयोग करूंगा धन्यवाद @RobW भी, jsfiddle लिंक लगता है लोडिंग पेज पर अटक जाना :(
न्यूकमैन न्यूमैन

3

JSONP के साथ सर्व का उपयोग करने का प्रयास करें, मुझे लगता है कि वे इस प्रारूप का उपयोग करते समय इसकी पेशकश करते हैं।

इसके अलावा, उन्हें एक अच्छे तर्क सहित एक विस्तृत बग रिपोर्ट दर्ज करें कि मानक के अनुरूप क्यों होना चाहिए। स्रोत समस्या को समाप्त करने के अलावा कोई अन्य समाधान कोई वास्तविक समाधान नहीं है।

एक त्वरित-एन-गंदा फिक्स को पुन: स्थापित करने से पहले स्ट्रिंग को एक रेगेक्स के माध्यम से पाइप करना हो सकता है:

var obj = JSON.parse(str.replace(/(\{|,)\s*(.+?)\s*:/g, '$1 "$2":'));

या यदि आप एक और वाक्यविन्यास पार्सन चाहते हैं तो एक मौजूदा जावास्क्रिप्ट JSON पार्सर (जैसे यह ) को समायोजित करने का प्रयास करें ।



2

आपका विरासत में मिला हुआ सिंटैक्स आसानी से यमल द्वारा खाया जाना चाहिए, जो कि JSON का सुपरसेट है।

जावास्क्रिप्ट YAML पार्सर और डम्पर आज़माएं: http://nodeca.github.com/js-yaml/


2

@Derek D 朕, इस विधि को साझा करने के लिए धन्यवाद, मैं अपने कोड को साझा करना पसंद करता हूं जो वस्तुओं की एक सरणी को भी सख्त करने का समर्थन करता है।

export const stringifyObjectWithNoQuotesOnKeys = (obj_from_json) => {
    // In case of an array we'll stringify all objects.
    if (Array.isArray(obj_from_json)) {
        return `[${
                    obj_from_json
                        .map(obj => `${stringifyObjectWithNoQuotesOnKeys(obj)}`)
                        .join(",")
                }]` ;
    }
    // not an object, stringify using native function
    if(typeof obj_from_json !== "object" || obj_from_json instanceof Date || obj_from_json === null){
        return JSON.stringify(obj_from_json);
    }
    // Implements recursive object serialization according to JSON spec
    // but without quotes around the keys.
    return `{${
            Object
                .keys(obj_from_json)
                .map(key => `${key}:${stringifyObjectWithNoQuotesOnKeys(obj_from_json[key])}`)
                .join(",")
            }}`;
};

1
आपको JSON.stringifyInstof Date के लिए भी उपयोग करना चाहिए । साथ ही 'null'अगर obj_from_jsonअशक्त है तो वापस लौटें ।
सुदूर दिमित्री

1
मैंने सिर्फ @FarDmitry द्वारा उठाए गए बिंदुओं को तय किया है अगर दूसरी स्थिति को इस तरह से if(typeof obj_from_json !== "object" || obj_from_json instanceof Date || obj_from_json === null)
बदलना है

2

उपयोग JSON5.stringify

JSON5 , JSON का एक सुपरसेट है जो ES5 सिंटैक्स की अनुमति देता है, जिसमें अनक्लेटेड प्रॉपर्टी कीज़ भी शामिल है। JSON5 संदर्भ कार्यान्वयन ( json5एनपीएम पैकेज ) एक JSON5ऑब्जेक्ट प्रदान करता है जिसमें बिल्ट-इन JSONऑब्जेक्ट के समान ही args और शब्दार्थ के साथ एक ही तरीके हैं ।

यह अत्यधिक संभावना है कि आप जिस सेवा का उपयोग कर रहे हैं वह इस पुस्तकालय का उपयोग कर रही है।


1

CSVJSON के JSON ब्यूटिफायर में कुंजियों पर उद्धरण छोड़ने का एक विकल्प है। यदि आप सिर्फ कोड चाहते हैं, तो आप इसे GitHub रेपो से कॉपी कर सकते हैं। मैंने इसके लिए समर्थन जोड़ने के लिए डगलस क्रॉकफोर्ड के JSON2 को संशोधित किया


बस csvjson.com/json_beautifier पर क्लिक किया और मुझे उम्मीद से अलग पेज मिला ... hacked by AnoaGhost
RedactedProfile

अब साफ हो गया। असुविधा के लिए खेद है।
मार्टिन ड्रेप्यू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.