मैं JSON में नई कहानियों को कैसे संभालूं?


289

मैंने कुछ JSON उत्पन्न किया है और मैं इसे जावास्क्रिप्ट में किसी ऑब्जेक्ट में खींचने की कोशिश कर रहा हूं। मुझे त्रुटियाँ मिलती रहती हैं। यहाँ मेरे पास क्या है:

var data = '{"count" : 1, "stack" : "sometext\n\n"}';
var dataObj = eval('('+data+')');

यह मुझे एक त्रुटि देता है:

unterminated string literal

इसके साथ JSON.parse(data), मुझे समान त्रुटि संदेश दिखाई देते हैं: " Unexpected token ↵" क्रोम में, और unterminated string literalफ़ायरफ़ॉक्स और IE में " "।

जब मैं बाहर ले जाना \nके बाद sometextत्रुटि दोनों ही मामलों में चला जाता है। मुझे लगता है कि क्यों \nबनाता है evalऔर JSON.parseअसफल हो सकता है।


19
Eval के बजाय एक असली json पार्सर का उपयोग करने का प्रयास करें।
एरिक

जवाबों:


368

मुझे लगता है कि यह वही है जो आप चाहते हैं:

var data = '{"count" : 1, "stack" : "sometext\\n\\n"}';

(आपको अपने स्ट्रिंग में "\" से बचने की आवश्यकता है (इसे एक डबल - "\" में बदलकर), अन्यथा यह JSON स्रोत में एक नई पंक्ति बन जाएगी, न कि JSON डेटा। "


101
यह निश्चित रूप से सही है, लेकिन मैं ऐसा करने के लिए कारण जोड़ना चाहूंगा: ietf.org/rfc/rfc4627.txt पर JSON युक्ति में धारा 2.5 में यह वाक्य है: "सभी यूनिकोड वर्णों को भीतर रखा जा सकता है। वर्णों को छोड़कर उद्धरण चिह्नों को छोड़ना चाहिए: उद्धरण चिह्न, रिवर्स सॉलिडस, और नियंत्रण वर्ण (U + 001F के माध्यम से U + 0000)। " चूंकि एक नई रेखा एक नियंत्रण चरित्र है, इसलिए इसे बच जाना चाहिए।
डेनियल कुल्मन

1
Www.json.org के अनुसार, JSON स्ट्रिंग्स में नियंत्रण अनुक्रम "\ n" को स्वीकार करता है - और यदि आप JSON.parse (['' a a \\ na "']) [1] .charCodeAt () को आज़माते हैं; वह 10 दिखाएगा - जो पिछली बार मैंने चेक किया था "लाइनफीड"। --- BTW: चीखना बंद करो!
BlaM

+ 1. मुझे JSON-एन्कोडिंग को समझने में समस्या हो रही थी, लेकिन "JSON स्रोत में एक नई रेखा बन जाएगी, न कि JSON डेटा" मेरे लिए इसे स्पष्ट कर दिया।
अमुकुंगुज़ि

44

आपको एक फ़ंक्शन की आवश्यकता होगी जो मामले में प्रतिस्थापित \nकरता है एक स्ट्रिंग शाब्दिक नहीं है।\\ndata

function jsonEscape(str)  {
    return str.replace(/\n/g, "\\\\n").replace(/\r/g, "\\\\r").replace(/\t/g, "\\\\t");
}

var data = '{"count" : 1, "stack" : "sometext\n\n"}';
var dataObj = JSON.parse(jsonEscape(data));

परिणाम dataObjहोगा

Object {count: 1, stack: "sometext\n\n"}

3
आपको अपने भागने के पात्रों (यानी .replace("\\n", "\\\\n")) से बचने की जरूरत है और मैं कई उदाहरणों (यानी .replace(/\n/g, "\\\\n")) की जगह लेने के लिए
rexx

2
आपको भागने के पात्रों से बचने की आवश्यकता क्यों है? मेरा मतलब है जैसे कुछ .replace("\n", "\\n")काम ठीक करना चाहिए !! उदाहरण के लिए, var test = [{"description":"Some description about the product. This can be multi-line text."}]; console.log(JSON.parse(test.replace(/\n/g, "\\n")));ऑब्जेक्ट को ब्राउजर कंसोल पर पूरी तरह से ठीक करेगा[{"description":"Some description about the product.\nThis can be multi-line text."}]
Fr0zenFyr

BTW, उपरोक्त टिप्पणी में, मूल JSON स्ट्रिंग में एक नई लाइन है, जिसे स्टैकओवरफ़्लो के टिप्पणी फ़ॉर्मेटर द्वारा हटा दिया जाता है .. आप देख सकते हैं कि अंतिम आउटपुट को प्रतिस्थापित करने के बाद \nमूल्य में एक नई-लाइन चार सम्मिलित करनी चाहिए ।
Fr0zenFyr

1
-1 यह उत्तर पहले अमान्य JSON (चूंकि नईलाइन एक नियंत्रण चरित्र है) की एक स्ट्रिंग का निर्माण करता है, फिर इसे अपूर्ण प्रतिस्थापनों की एक श्रृंखला के साथ ठीक करने की कोशिश करता है (3 से अधिक नियंत्रण वर्ण हैं)। फिर इसे बंद करने के लिए, यह evalफ़ंक्शन का उपयोग करने का प्रबंधन भी करता है । 17 अपवित्र ???
फिल

1
ऐसे उद्धरण चिह्नों के बारे में जो बच निकलने की जरूरत है?
अकेले

8

विनिर्देश के अनुसार, http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf :

एक स्ट्रिंग उद्धरण चिह्नों ( U+0022) के साथ लिपटे यूनिकोड कोड बिंदुओं का एक अनुक्रम है । सभी वर्ण अक्षर हैं जो बच गए किया जाना चाहिए के अलावा उद्धरण चिह्नों के भीतर रखा जा सकता है: उद्धरण चिह्न ( U+0022), रिवर्स सोलिडस ( U+005C), और नियंत्रण वर्ण U+0000के लिए U+001F। कुछ चरित्रों के दो-चरित्र पलायन अनुक्रम प्रतिनिधित्व हैं।

तो आप सीधे पास 0x0Aया 0x0Cकोड नहीं कर सकते । यह निषिद्ध है! विनिर्देश निम्न से कुछ अच्छी तरह से परिभाषित कोड के लिए एस्केप अनुक्रम का उपयोग करने का सुझाव देता U+0000है U+001F:

  • \fप्रपत्र फ़ीड वर्ण ( U+000C) का प्रतिनिधित्व करता है ।
  • \nपंक्ति फ़ीड वर्ण ( U+000A) का प्रतिनिधित्व करता है ।

जैसा कि अधिकांश प्रोग्रामिंग भाषाएं \उद्धृत करने के लिए उपयोग करती हैं , आपको एस्केप सिंटैक्स से बचना चाहिए (डबल-एस्केप - एक बार भाषा / मंच के लिए, एक बार JSON के लिए):

jsonStr = "{ \"name\": \"Multi\\nline.\" }";

3

उदाहरण के लिए, क्लाइंट ब्राउज़र में मान प्राप्त करते समय आप JSON फ़ील्ड का मान लिखते समय सर्वर पर अपनी स्ट्रिंग से बच सकते हैं और इसे अनस्केप कर सकते हैं।

सभी प्रमुख ब्राउज़रों के जावास्क्रिप्ट कार्यान्वयन में अनसैप्ड कमांड है।

उदाहरण:

सर्वर पर:

response.write "{""field1"":""" & escape(RS_Temp("textField")) & """}"

ब्राउज़र में:

document.getElementById("text1").value = unescape(jsonObject.field1)

2

आप स्ट्रिंग से बचने के लिए इस C # फ़ंक्शन को देखना चाहते हैं:

http://www.aspcode.net/C-encode-a-string-for-JSON-JavaScript.aspx

public static string Enquote(string s)  
{ 
    if (s == null || s.Length == 0)  
    { 
        return "\"\""; 
    } 
    char         c; 
    int          i; 
    int          len = s.Length; 
    StringBuilder sb = new StringBuilder(len + 4); 
    string       t; 

    sb.Append('"'); 
    for (i = 0; i < len; i += 1)  
    { 
        c = s[i]; 
        if ((c == '\\') || (c == '"') || (c == '>')) 
        { 
            sb.Append('\\'); 
            sb.Append(c); 
        } 
        else if (c == '\b') 
            sb.Append("\\b"); 
        else if (c == '\t') 
            sb.Append("\\t"); 
        else if (c == '\n') 
            sb.Append("\\n"); 
        else if (c == '\f') 
            sb.Append("\\f"); 
        else if (c == '\r') 
            sb.Append("\\r"); 
        else 
        { 
            if (c < ' ')  
            { 
                //t = "000" + Integer.toHexString(c); 
                string t = new string(c,1); 
                t = "000" + int.Parse(tmp,System.Globalization.NumberStyles.HexNumber); 
                sb.Append("\\u" + t.Substring(t.Length - 4)); 
            }  
            else  
            { 
                sb.Append(c); 
            } 
        } 
    } 
    sb.Append('"'); 
    return sb.ToString(); 
} 

3
यह बचता क्यों है >?
कुछ नहीं

0

मैंने इस फ़ंक्शन का उपयोग JSON डेटा पार्स करने के लिए डेटा में न्यूलाइन या अन्य वर्णों को छीनने के लिए किया:

function normalize_str($str) {

    $invalid = array(
        'Š'=>'S', 'š'=>'s',  'Đ'=>'Dj', 'đ'=>'dj', 'Ž'=>'Z', 'ž'=>'z',
        'Č'=>'C', 'č'=>'c',  'Ć'=>'C',  'ć'=>'c',  'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A',
        'Ä'=>'A', 'Å'=>'A',  'Æ'=>'A',  'Ç'=>'C',  'È'=>'E', 'É'=>'E', 'Ê'=>'E', 'Ë'=>'E',
        'Ì'=>'I', 'Í'=>'I',  'Î'=>'I',  'Ï'=>'I',  'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O',
        'Õ'=>'O', 'Ö'=>'O',  'Ø'=>'O',  'Ù'=>'U',  'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y',
        'Þ'=>'B', 'ß'=>'Ss', 'à'=>'a',  'á'=>'a',  'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a',
        'æ'=>'a', 'ç'=>'c',  'è'=>'e',  'é'=>'e',  'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i',
        'î'=>'i', 'ï'=>'i',  'ð'=>'o',  'ñ'=>'n',  'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o',
        'ö'=>'o', 'ø'=>'o',  'ù'=>'u',  'ú'=>'u',  'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b',
        'ÿ'=>'y', 'Ŕ'=>'R',  'ŕ'=>'r',
        "`" => "'", "´" => "'",  '"' => ',',  '`' => "'",
        '´' => "'", '"' => '\"', '"' => "\"", '´' => "'",
        "&acirc;€™" => "'",
        "{" => "",
        "~" => "",  "–" => "-",  "'" => "'",  "     " => " ");

    $str = str_replace(array_keys($invalid), array_values($invalid), $str);

    $remove = array("\n", "\r\n", "\r");
    $str = str_replace($remove, "\\n", trim($str));

    //$str = htmlentities($str, ENT_QUOTES);

    return htmlspecialchars($str);
}

echo normalize_str($lst['address']);

9
अधिकांश भाषाओं में आपके पास अपने स्वयं के मानचित्रण फ़ंक्शन को लिखने की तुलना में यूनिकोड स्ट्रिंग्स से उच्चारण को छीनने के बेहतर तरीके हैं। अजगर में एक उदाहरण के लिए इस सवाल को देखें: stackoverflow.com/questions/517923/…
मिनीक्वार्क

फिर हमारे पास अलग-अलग भाषाओं में विशेष वर्णों को नियंत्रित करने के कई तरीके हैं।
शिवराजआरएच

2
यह सामान्य रूप से उन्हें पट्टी करने के लिए हर तरह का बुरा है। बेहतर एक्सएमएल संख्यात्मक चरित्र संदर्भ के रूप में उन्हें सांकेतिक शब्दों में बदलना और फिर अंत प्राप्त करने पर डिकोड।
अन्नपूर्णिक

0

JSON.stringify

JSON.stringify(`{ 
  a:"a"
}`)

उपरोक्त स्ट्रिंग को परिवर्तित करेगा

"{ \n      a:\"a\"\n    }"

जैसा कि यहाँ बताया गया है

json कड़ा

यह फ़ंक्शन इनपुट स्ट्रिंग की शुरुआत और अंत में दोहरे उद्धरण जोड़ता है और विशेष JSON वर्णों से बच जाता है। विशेष रूप से, एक नई पंक्ति को \ n वर्ण द्वारा प्रतिस्थापित किया जाता है, एक टैब को \ t वर्ण द्वारा प्रतिस्थापित किया जाता है, एक बैकस्लैश को दो बैकस्लैश \ _ द्वारा प्रतिस्थापित किया जाता है, और प्रत्येक उद्धरण चिह्न से पहले एक बैकस्लैश रखा जाता है।


4
यह आठ अन्य मौजूदा उत्तरों के साथ ग्यारह साल पुराने प्रश्न का केवल एक कोड है। यह कोड की व्याख्या करने के लिए उपयोगी है, और यह भी समझाने के लिए कि आपके उत्तर के प्रश्न का कौन सा नया पहलू है, और यदि समय बीतने और नए संस्करणों की रिहाई आपके उत्तर को प्रभावित करती है।
जेसन एलर

-1

Json_encode (PHP 5 में उपलब्ध) का अनुकरण करने के लिए PHP 4 में एक वर्ग बनाते समय मुझे उस समस्या का सामना करना पड़ा। यहाँ मैं क्या लेकर आया हूँ:

class jsonResponse {
    var $response;

    function jsonResponse() {
        $this->response = array('isOK'=>'KO', 'msg'=>'Undefined');
    }

    function set($isOK, $msg) {
        $this->response['isOK'] = ($isOK) ? 'OK' : 'KO';
        $this->response['msg'] = htmlentities($msg);
    }

    function setData($data=null) {
        if(!is_null($data))
            $this->response['data'] = $data;
        elseif(isset($this->response['data']))
            unset($this->response['data']);
    }

    function send() {
        header('Content-type: application/json');
        echo '{"isOK":"' . $this->response['isOK'] . '","msg":' . $this->parseString($this->response['msg']);
        if(isset($this->response['data']))
            echo ',"data":' . $this->parseData($this->response['data']);
        echo '}';
    }

    function parseData($data) {
        if(is_array($data)) {
            $parsed = array();
            foreach ($data as $key=>$value)
                array_push($parsed, $this->parseString($key) . ':' . $this->parseData($value));
            return '{' . implode(',', $parsed) . '}';
        }
        else
            return $this->parseString($data);
    }

    function parseString($string) {
            $string = str_replace("\\", "\\\\", $string);
            $string = str_replace('/', "\\/", $string);
            $string = str_replace('"', "\\".'"', $string);
            $string = str_replace("\b", "\\b", $string);
            $string = str_replace("\t", "\\t", $string);
            $string = str_replace("\n", "\\n", $string);
            $string = str_replace("\f", "\\f", $string);
            $string = str_replace("\r", "\\r", $string);
            $string = str_replace("\u", "\\u", $string);
            return '"'.$string.'"';
    }
}

मैंने यहां बताए गए नियमों का पालन किया । मैंने केवल उसी चीज़ का उपयोग किया जिसकी मुझे आवश्यकता थी, लेकिन मुझे लगता है कि आप इसे उस भाषा में अपनी आवश्यकताओं के अनुकूल बना सकते हैं जिसका आप उपयोग कर रहे हैं। मेरे मामले में समस्या नई कहानियों के बारे में नहीं थी जैसा कि मैंने मूल रूप से सोचा था, लेकिन इसके बारे में / बच नहीं पाया। मुझे उम्मीद है कि यह किसी और को थोड़ा सिरदर्द से रोकता है जो मैंने सोचा था कि मैंने क्या गलत किया है।


2
Json.org पर निर्दिष्ट नियंत्रण वर्णों के लिए 6 शॉर्टहैंड सभी नियंत्रण वर्णों की संपूर्ण सूची नहीं है। परिणामस्वरूप, यह फ़ंक्शन अमान्य JSON उत्पन्न कर सकता है।
फिल

-5

जैसा कि मैंने आपको प्रश्न को समझते हैं, यह सीधे JSON को पार्स है क्योंकि आप कर सकते हैं आपके JSON अपने कोड में कॉपी-पेस्ट के बारे में नहीं है - इसलिए यदि इस मामले तो बस कॉपी आपके JSON करने के लिए प्रत्यक्ष है dataObjएकल उद्धरण के साथ लपेटकर बिना चर (टिप: eval==evil)

var dataObj = {"count" : 1, "stack" : "sometext\n\n"};

console.log(dataObj);

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