简体   繁体   English

带有转义字符的 JSON.parse

[英]JSON.parse with escape characters

Trying to get a handle on JSON.parse and having a difficult time understanding how escape characters are handled;试图处理 JSON.parse 并且很难理解转义字符是如何处理的; specifically - why does:特别是 - 为什么:

JSON.parse('["\\\\\\"\\"a\\""]')

Evaluate to:评估为:

["\""a""]

How do the multiple backslashes work with each other?多个反斜杠如何相互配合?

Thanks!谢谢!

First of all, let's clarify what value we're actually working with:首先,让我们澄清一下我们实际使用的值是什么:

var str = '["\\\\\\"\\"a\\""]';
console.log(str);
// => ["\\\"\"a\""]

As you can see, half of those backslashes had nothing to do with JSON.如您所见,其中一半的反斜杠与 JSON 无关。 They were just escaping characters in the JavaScript string.它们只是转义 JavaScript 字符串中的字符。 The actual characters of that string are these:该字符串的实际字符是这些:

["\\\"\"a\""]

We know that the square brackets ( [] ) indicate a JSON array, and the outermost quotation marks indicate a JSON string, so let's drop those:我们知道方括号 ( [] ) 表示一个 JSON 数组,最外面的引号表示一个 JSON 字符串,所以让我们去掉那些:

\\\"\"a\"

Now, to figure out what JavaScript string this JSON will deserialize to, let's break it up into its parts:现在,要弄清楚此 JSON 将反序列化为哪个 JavaScript 字符串,让我们将其分解为几个部分:

\\  \"  \"   a  \"
 1   2   3   4   5

I've paired up each backslash with the character that follows it (which is sometimes another backslash—backslashes are escaped with backslashes just like quotation marks are).我将每个反斜杠与它后面的字符配对(有时是另一个反斜杠——反斜杠就像引号一样用反斜杠转义)。 Now for each character that's preceded by a backslash we just drop the backslash:现在对于前面有反斜杠的每个字符,我们只需删除反斜杠:

\   "   "   a   "
1   2   3   4   5

Now mash it all together again:现在再次将它们混合在一起:

\""a"

Did it work?它起作用了吗?

var str = '["\\\\\\"\\"a\\""]';
var array = JSON.parse(str);
console.log(array[0]);
// => \""a"

Yep!是的!

PS Because JSON and JavaScript escaping work the same way, you could apply the same process to the original JavaScript string: PS 因为 JSON 和 JavaScript 转义的工作方式相同,所以您可以对原始 JavaScript 字符串应用相同的过程:

["\\\\\\"\\"a\\""]

Split it up again:再次拆分:

[   "  \\  \\  \\   "  \\   "   a  \\   "   "   ]
1   2   3   4   5   6   7   8   9  10  11  12  13

You'll notice that in this case only backslashes are escaped—that's because in our JavaScript the string was surrounded by single-quotes, so the double-quotes didn't have to be escaped.你会注意到,在这种情况下,只有反斜杠被转义——这是因为在我们的 JavaScript 中,字符串被单引号包围,所以双引号不必被转义。 Now, drop the initial backslashes again and we get:现在,再次删除最初的反斜杠,我们得到:

[   "   \   \   \   "   \   "   a   \   "   "   ]
1   2   3   4   5   6   7   8   9  10  11  12  13

And squash it together again:并再次将其压扁:

["\\\"\"a\""]

You'll recognize this as the original value we started with.您会认识到这是我们开始时的原始值。

In this case JavaScript escaping actually works in steps.在这种情况下,JavaScript 转义实际上是分步进行的。 Basically meaning the string is escaped initially, but then the result after that is then escaped again.基本上意味着字符串最初被转义,但之后的结果再次被转义。 So the first escape acts like so:所以第一个逃生行为是这样的:

Step 1: ["\\\\\\\\\\\\"\\\\"a\\\\""] ==> ["(\\\\)(\\\\)(\\\\)"\\(\\")a\\(\\")"] ==> ["\\\\\\"\\"a\\""]第 1 步: ["\\\\\\\\\\\\"\\\\"a\\\\""] ==> ["(\\\\)(\\\\)(\\\\)"\\(\\")a\\(\\")"] ==> ["\\\\\\"\\"a\\""]

In this first step each \\\\ converts to a \\ and \\" to a " .在这第一步中,每个\\\\转换为\\\\"转换为" A better look at which items are being converted (I've added (..) around the converted items in this step, where (\\\\) converts to \\ and (\\") converts to " ).更好地查看正在转换的项目(我在此步骤中在转换后的项目周围添加了(..) ,其中(\\\\)转换为\\并且(\\")转换为" )。

Step2: ["\\\\\\"\\"a\\""] ==> ["(\\\\)(\\")(\\")a(\\")"] ==> ["\\""a""] Step2: ["\\\\\\"\\"a\\""] ==> ["(\\\\)(\\")(\\")a(\\")"] ==> ["\\""a""]

the same problem with me but i solve with this sample code.我也有同样的问题,但我用这个示例代码解决了。

def escape(str):
    str = str.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n').
        replace('\t', '\\t')
    result = []
    for ch in str:
        n = ord(ch)
        if n < 32:
            h = hex(n).replace('0x', '')
            result += ['\\u%s%s' % ('0'*(4-len(h)), h)]
        else:
            result += [ch]
    return ''.join(result)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM