var dataObj = eval'"/>

关于javascript:如何处理JSON中的换行符?

关于javascript:如何处理JSON中的换行符?

How do I handle newlines in JSON?

我生成了一些JSON,并尝试将其拉入JavaScript中的对象。 我不断出错。 这是我所拥有的:

1
2
3
4
var data = '{"count" : 1,"stack" :"sometext

"}'
;
var dataObj = eval('('+data+')');

这给我一个错误:

1
unterminated string literal

使用JSON.parse(data),我会看到类似的错误消息:Chrome中为" Unexpected token ?",而在Firefox和IE中为" unterminated string literal"。

当我在sometext之后取出
时,两种情况下的错误都会消失。 我似乎无法弄清楚为什么
使evalJSON.parse失败。


我想这就是你想要的:

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

(您需要对字符串中的""进行转义(将其转换为双"-""),否则它将成为JSON源中的换行符,而不是JSON数据。)


如果data不是字符串文字,您将需要一个函数将
替换为\

1
2
3
4
5
6
7
8
9
10
11
12
function jsonEscape(str)  {
    return str.replace(/
/g,"\\\
"
).replace(/
/g,"\\\
"
).replace(/\t/g,"\\\\t");
}

var data = '{"count" : 1,"stack" :"sometext

"}'
;
var dataObj = JSON.parse(jsonEscape(data));

结果dataObj将是

1
2
3
Object {count: 1, stack:"sometext

"
}


根据规范,http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf:

A string is a sequence of Unicode code points wrapped with quotation marks
(U+0022). All characters may be placed within the quotation marks except for the
characters that must be escaped: quotation mark (U+0022), reverse solidus
(U+005C), and the control characters U+0000 to U+001F. There are two-character
escape sequence representations of some characters.

因此,您不能直接传递0x0A0x0C代码。这是被禁止的!该规范建议对U+0000U+001F的一些明确定义的代码使用转义序列:

  • \f代表换页字符(U+000C)。

  • 表示换行符(U+000A)。

由于大多数编程语言都使用\进行引用,因此您应转义转义语法(两次转义-一次用于语言/平台,一次用于JSON本身):

1
2
jsonStr ="{ "name": "Multi\
line." }";

例如,您可以在写入JSON字段的值时在服务器上转义字符串,而在客户端浏览器中获取值时取消转义字符串。

所有主要浏览器的JavaScript实现都具有unescape命令。

例:

在服务器上:

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

在浏览器中:

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

我使用此函数来去除数据中的换行符或其他字符以解析JSON数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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'=>'Y',
        'T'=>'B', '?'=>'Ss', 'à'=>'a',  'á'=>'a',  'a'=>'a', '?'=>'a', '?'=>'a', '?'=>'a',
        '?'=>'a', '?'=>'c',  'è'=>'e',  'é'=>'e',  'ê'=>'e', '?'=>'e', 'ì'=>'i', 'í'=>'i',
        '?'=>'i', '?'=>'i',  'e'=>'o',  '?'=>'n',  'ò'=>'o', 'ó'=>'o', '?'=>'o', '?'=>'o',
        '?'=>'o', '?'=>'o',  'ù'=>'u',  'ú'=>'u',  '?'=>'u', 'y'=>'y', 'y'=>'y', 't'=>'b',
        '?'=>'y', '?'=>'R',  '?'=>'r',
       "`" =>"'","′" =>"'",  '"' => ',',  '`' =>"'",
        '′' =>"'", '"' => '"', '"' =>""", '′' =>"'",
       "â€?" =>"'
",
       "
{" =>"",
       "
~" =>"", "" =>"-", "'" =>"'", "    " =>"");

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

    $remove = array("

","

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

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

    return htmlspecialchars($str);
}

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

您可能需要研究以下C#函数来转义字符串:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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 == '
')
            sb.Append("
\
");
        else if (c == '\f')
            sb.Append("
\\f");
        else if (c == '
')
            sb.Append("
\
");
        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();
}


我在PHP4中创建一个类来模拟json_encode(在PHP5中可用)时遇到了这个问题。这是我想出的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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("

","\
", $string);
            $string = str_replace("
\f","\\f", $string);
            $string = str_replace("

","\
", $string);
            $string = str_replace("
\u","\\u", $string);
            return '"
'.$string.'"';
    }
}

我遵循这里提到的规则。我只使用了我需要的内容,但是我认为您可以使用所使用的语言来使其适应您的需求。在我的情况下,问题不是我最初想到的换行符,而是/未被逃脱。我希望这可以防止其他人因我弄清楚自己做错了什么而感到头疼。


据我所知,这与解析JSON无关,因为您可以将JSON直接复制粘贴到代码中-因此,在这种情况下,只需将JSON直接复制到dataObj变量,而不用单引号引起来(提示:eval==evil)

1
2
3
4
5
var dataObj = {"count" : 1,"stack" :"sometext

"
};

console.log(dataObj);


推荐阅读