我已经生成了一些JSON,我试图把它拉到一个对象在JavaScript。我总是出错。以下是我所拥有的:

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

这给了我一个错误:

unterminated string literal

使用JSON.parse(data),我看到类似的错误消息:在Chrome中“意外的令牌()”,在Firefox和IE中“未终止的字符串文字”。

当我在sometext后面去掉\n时,两种情况下错误都消失了。我似乎不明白为什么\n使eval和JSON。解析失败。


当前回答

TLDR:作者问题的解决方案。

您生成的json是错误的,因为它在其中一个值中包含换行符。要在其中一个值中生成一个表示(不包含)换行符的json,您可以使用:

使用字符串。原始的文字:

var data = String.raw`{"count" : 1, "stack" : "sometext\n\n"}`;

或应用JSON。Stringify为一个javascript对象(首先是类似json的)。

var data = JSON.stringify({"count" : 1, "stack" : "sometext\n\n"});

出于某种原因,这里所有的答案都集中在如何在JavaScript中解析JSON字符串表示,这可能会导致关于如何在实际JSON中表示换行符的困惑。后者不依赖于语言。

严格根据题目:

我如何处理JSON中的换行符?

让我们假设你在node中使用以下代码解析一个JSON文件(它可以是任何语言):


let obj = JSON.parse(fs.readFileSync('file.json'));
console.log(obj.mykey)

下面是file.json中每个可能内容的输出:

输入1:

{
  "mykey": "my multiline
   value"
}

输出1:

SyntaxError: Unexpected token

输入2:

{
  "mykey": "my multiline\nvalue"
}

输出2:

my multiline
value

输入3:

{
  "mykey": "my multiline\\nvalue"
}

3:输出

my multiline\nvalue

结论1:

要在json文件中表示换行符,我们应该使用\n字符。我们应该用\\n来表示\n。


我们如何使用JavaScript(而不是输入文件)定义上述每个输入:

当我们需要在JavaScript中定义一个包含JSON的字符串时,事情会发生一些变化,因为\n对于JavaScript也有特殊的意义。但还要注意String。原始文字修复了这个问题。

Input1:

let input1 = '{"mykey": "my multiline\nvalue"}'

//OR
let input1 = `{
  "mykey": "my multiline
   value"
}`;
//(or even)
let input1 = `{
  "mykey": "my multiline\nvalue"
}`;

//OR
let input1 = String.raw`{
  "mykey": "my multiline
   value"
}`;

console.log(JSON.parse(input1).mykey);

//SyntaxError: Unexpected token
//in JSON at position [..]

输入2:

let input2 = '{"mykey": "my multiline\\nvalue"}'

//OR
let input2 = `{
  "mykey": "my multiline\\nvalue"
}`;

//OR (Notice the difference from default literal)
let input2 = String.raw`{
  "mykey": "my multiline\nvalue"
}`;

console.log(JSON.parse(input2).mykey);

//my multiline
//value

输入3:

let input3 = '{"mykey": "my multiline\\\\nvalue"}'

//OR
let input3 = `{
  "mykey": "my multiline\\\\nvalue"
}`;

//OR (Notice the difference from default literal)
let input3 = String.raw`{
  "mykey": "my multiline\\nvalue"
}`;

console.log(JSON.parse(input3).mykey);

//my multiline\nvalue

结论2:

要在javascript中定义一个json字符串,最简单的方法是使用string。raw,因为它不需要任何转义(除了backtick,它像这个字符串一样转义。生'abc ${“’”}def”)。

当然,在javascript中创建json最简单的方法通常是将javascript对象转换为json(使用json .stringify)。


重要提示:

Don't get confused by how chrome/firefox devtools preview variables containing newlines (e.g. when you just write the variable name and press Enter). When previewing objects they always represent newlines of string values like \n. But, when previewing a string (e.g. dataObj.stack) firefox will show a newline as an empty line but chrome will still show it as \n. So, to be safe, you should always preview with console.log(dataObj.stack) to better understand what's actually contained inside the specific variable.

其他回答

我使用这个函数来剥离数据中的换行符或其他字符来解析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',
        "`" => "'", "´" => "'",  '"' => ',',  '`' => "'",
        '´' => "'", '"' => '\"', '"' => "\"", '´' => "'",
        "’" => "'",
        "{" => "",
        "~" => "",  "–" => "-",  "'" => "'",  "     " => " ");

    $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']);

我在PHP 4中创建一个类来模拟json_encode(在PHP 5中可用)时遇到了这个问题。下面是我想到的:

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.'"';
    }
}

我遵循了这里提到的规则。我只使用了我需要的,但我认为您可以根据您所使用的语言对其进行调整以满足您的需要。在我的情况下,问题并不像我最初认为的那样是换行,而是关于/没有被转义。我希望这能防止别人像我一样头疼地发现我做错了什么。

TLDR:作者问题的解决方案。

您生成的json是错误的,因为它在其中一个值中包含换行符。要在其中一个值中生成一个表示(不包含)换行符的json,您可以使用:

使用字符串。原始的文字:

var data = String.raw`{"count" : 1, "stack" : "sometext\n\n"}`;

或应用JSON。Stringify为一个javascript对象(首先是类似json的)。

var data = JSON.stringify({"count" : 1, "stack" : "sometext\n\n"});

出于某种原因,这里所有的答案都集中在如何在JavaScript中解析JSON字符串表示,这可能会导致关于如何在实际JSON中表示换行符的困惑。后者不依赖于语言。

严格根据题目:

我如何处理JSON中的换行符?

让我们假设你在node中使用以下代码解析一个JSON文件(它可以是任何语言):


let obj = JSON.parse(fs.readFileSync('file.json'));
console.log(obj.mykey)

下面是file.json中每个可能内容的输出:

输入1:

{
  "mykey": "my multiline
   value"
}

输出1:

SyntaxError: Unexpected token

输入2:

{
  "mykey": "my multiline\nvalue"
}

输出2:

my multiline
value

输入3:

{
  "mykey": "my multiline\\nvalue"
}

3:输出

my multiline\nvalue

结论1:

要在json文件中表示换行符,我们应该使用\n字符。我们应该用\\n来表示\n。


我们如何使用JavaScript(而不是输入文件)定义上述每个输入:

当我们需要在JavaScript中定义一个包含JSON的字符串时,事情会发生一些变化,因为\n对于JavaScript也有特殊的意义。但还要注意String。原始文字修复了这个问题。

Input1:

let input1 = '{"mykey": "my multiline\nvalue"}'

//OR
let input1 = `{
  "mykey": "my multiline
   value"
}`;
//(or even)
let input1 = `{
  "mykey": "my multiline\nvalue"
}`;

//OR
let input1 = String.raw`{
  "mykey": "my multiline
   value"
}`;

console.log(JSON.parse(input1).mykey);

//SyntaxError: Unexpected token
//in JSON at position [..]

输入2:

let input2 = '{"mykey": "my multiline\\nvalue"}'

//OR
let input2 = `{
  "mykey": "my multiline\\nvalue"
}`;

//OR (Notice the difference from default literal)
let input2 = String.raw`{
  "mykey": "my multiline\nvalue"
}`;

console.log(JSON.parse(input2).mykey);

//my multiline
//value

输入3:

let input3 = '{"mykey": "my multiline\\\\nvalue"}'

//OR
let input3 = `{
  "mykey": "my multiline\\\\nvalue"
}`;

//OR (Notice the difference from default literal)
let input3 = String.raw`{
  "mykey": "my multiline\\nvalue"
}`;

console.log(JSON.parse(input3).mykey);

//my multiline\nvalue

结论2:

要在javascript中定义一个json字符串,最简单的方法是使用string。raw,因为它不需要任何转义(除了backtick,它像这个字符串一样转义。生'abc ${“’”}def”)。

当然,在javascript中创建json最简单的方法通常是将javascript对象转换为json(使用json .stringify)。


重要提示:

Don't get confused by how chrome/firefox devtools preview variables containing newlines (e.g. when you just write the variable name and press Enter). When previewing objects they always represent newlines of string values like \n. But, when previewing a string (e.g. dataObj.stack) firefox will show a newline as an empty line but chrome will still show it as \n. So, to be safe, you should always preview with console.log(dataObj.stack) to better understand what's actually contained inside the specific variable.

你可能想看看这个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(); 
} 

正如我理解你的问题,这不是关于解析JSON,因为你可以直接复制粘贴你的JSON到你的代码-所以如果是这种情况下,然后直接复制你的JSON到dataObj变量,而不包装它与单引号(提示:eval==evil)

var dataObj = {“count” : 1, “stack” : “sometext\n\n”}; console.log(dataObj);