如何在JSON中转义双引号

523

我想显示双引号,但它显示了其中一个反斜杠:

"maingame": {
    "day1": {
        "text1": "Tag 1",
        "text2": "Heute startet unsere Rundreise \\\"Example text\\\". Jeden Tag wird ein neues Reiseziel angesteuert bis wir.</strong> "
    }
}

在 HTML 渲染中,它显示为 "Example text"。什么是正确的方法?

8个回答

715

试试这个:

"maingame": {
  "day1": {
    "text1": "Tag 1",
     "text2": "Heute startet unsere Rundreise \" Example text\". Jeden Tag wird ein neues Reiseziel angesteuert bis wir.</strong> "
  }
}

(在引号前只需一个反斜杠(\))。


11
@DWGuru,这与评论无关,它是一个转义序列,如https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf(第9段 - 字符串)所述。其中写道:“引号内可以放置所有字符,除了必须转义的字符”,然后具体说明:“\”代表引号字符(U+0022)”。 - mastazi
35
不知何故,这在JS中不能用JSON.parse()实现。 - SacWebDeveloper
8
@SacWebDeveloper: var r = '{"a":"quotes\"here"}' // "{"a":"quotes"here"}". 你需要同样转义字符串中的反斜杠,因此使用三个反斜杠,即 var r = '{"a":"quotes\\\\\"here"}' // "{"a":"quotes\"here"}"。之后你就可以使用 JSON.parse(r) - Qwerty
3
@Qwerty 看起来你只需要双反斜杠。'{"a":"quotes\\"here"}' - SacWebDeveloper
3
@SacWebDeveloper是的,没错。因为在单引号' '里,双引号可以不用转义,我有点把两件事搞混了,发帖之后才意识到。但在"里仍然需要使用三重转义符 " \\\" "' \\" '. - Qwerty
显示剩余3条评论

70

何时何地应该使用\\"。如果你像我一样,当你发现这个帖子后,你会感到和我一样愚蠢。

如果你正在创建一个.json文本文件/流并从中导入数据,那么在双引号之前只需要一个反斜杠的主要答案:\"是你要找的。

但是,如果你像我一样,想让w3schools.com的"Tryit Editor"在JSON.parse(text)输出中有一个双引号,那么你要找的是三个反斜杠双引号\\\"。这是因为你正在HTML <script>块内构建文本字符串,第一个双反斜杠将单独的反斜杠插入到字符串变量中,然后以下的反斜杠双引号将双引号插入到字符串中,使得生成的脚本字符串包含标准答案的\",JSON解析器将将其解析为仅是双引号。

<script>
  var text="{";
  text += '"quip":"\\\"If nobody is listening, then you\'re likely talking to the wrong audience.\\\""';
  text += "}";
  var obj=JSON.parse(text);
</script>

+1:由于它是JavaScript文本字符串,双反斜杠双引号 \\" 也可以工作;因为在单引号字符串中,双引号不需要转义,例如'\"''"'在JS字符串中会得到相同的结果。


这个解决方案有助于在Swift版本中构建一个字符串,该字符串被添加到JSON POST的参数中。 - Nick N

23

如果你想在 JSON 中转义双引号,使用 \\ 进行转义。

例如,如果你想创建以下 JavaScript 对象的 JSON:

{time: '7 "o" clock'}

那么你必须以以下方式写作

'{"time":"7 \\"o\\" clock"}'

如果我们使用JSON.parse()来解析它

JSON.parse('{"time":"7 \\"o\\" clock"}')

结果将会是

{time: "7 "o" clock"}

这对我不起作用。我正在使用带有内置JSON解析器的Python。你在使用哪种编程语言? - GabrielChu
上述代码是为JavaScript而不是Python编写的。 - manas
你最后的例子可能会误导人,因为你没有显示引号被转义。我用Firefox测试过了,它正确地将字符串显示为'7 "o" clock'(即使用单引号来显示至少包含一个双引号的字符串)。如果字符串同时包含单引号和双引号,它也会切换到反引号。如果它包含所有三个引号,它将使用双引号并转义双引号。 - Alexis Wilke

20

显示反斜杠是因为您同时转义了反斜杠。

除了双引号之外,如果想在JSON引用字符串中包含反斜杠,还必须转义反斜杠。但是,如果您打算在转义序列中使用反斜杠,显然您不应该转义它。


15
如果你在使用JavaScript、Python等语言,可以使用原始字符串(Python的r''或JavaScript的String.raw或类似的方式)。它们使得编写JSON字符串更加容易,因为它们避免了多次转义处理。
console.log(JSON.parse(String.raw`"This is a double quote >> \" <<"`))
// => This is a double quote >> " <<

更深入了解
在编写代码时,有时会因为字符串转义序列被多次处理而导致对JSON字符串的混淆。一次是在编程语言中,另一次是在JSON解析器中(例如在Javascript中的JSON.parse()或类似的函数)。
使用编程语言的打印函数来查看在编程语言中发生的转义可以让人感到困惑。
例如,当您直接在Javascript repl中输入字符串时,它会以这种方式显示。
'Two newlines:\n\nTab here >>\t<<\n\nBackslash here >>\\<<'
// => 'Two newlines:\n\nTab here >>\t<<\n\nBackslash here >>\\<<'

但是当你使用console.log()打印这个字符串时,它会以这种方式显示
console.log('Two newlines:\n\nTab here >>\t<<\n\nBackslash here >>\\<<')
/* =>
Two newlines:

Tab here >> <<

Backslash here >>\<<
*/

当JavaScript遇到一个字符串时,它会在将其传递给函数之前'评估'转义序列,也就是说,它会将每个\n替换为换行符,每个\t替换为制表符等等。
因此,通过console.log()输出字符串可以更好地了解发生了什么。

如何在JavaScript中对JSON中的单引号进行编码

要在JavaScript中将"写入JSON,可以使用
console.log(JSON.parse('"This is a double quote >> \\" <<"'));
// => This is a double quote >> " <<

在Python和其他编程语言中,这个过程是类似的。

逐步操作:

JavaScript使用转义序列规则来评估字符串,根据JavaScript规范将\n替换为换行符,\t替换为制表符等等。
在我们的例子中,它将\\替换为\
结果字符串为"This is a double quote >> \" <<"
我们加上外部的双引号,使其成为一个有效的JSON字符串。
JavaScript将结果传递给JSON.parse()函数。
JSON.parse根据JSON标准使用转义序列规则来评估字符串,将\n替换为换行符,\t替换为制表符等等。在我们的例子中,
它看到的第一个字符是",所以它知道这是一个JSON字符串。
在JSON字符串内部,它看到\"。通常"会结束JSON字符串,但是因为"\转义了,它知道这不是字符串的结束,而是将\"替换为一个双引号字符。
它看到的最后一个字符是",所以它知道这是JSON字符串的结束。
解析后的结果字符串为This is a double quote >> " <<。注意外部的双引号也消失了。
原始字符串使事情变得更容易
Javascript的String.raw模板函数和Python的r''字符串不会对任何转义序列进行评估,因此它使得推理变得更加容易和不容易混淆。
console.log(JSON.parse(String.raw`"This is a double quote >> \" <<"`))
// => This is a double quote >> " <<

12
请注意,当内容被“双重编码”时,最常发生这种情况,这意味着编码算法已经意外地调用了两次。
第一次调用将编码“text2”值: 从:Heute startet unsere Rundreise "Example text". Jeden Tag wird ein neues Reiseziel angesteuert bis wir. 到:Heute startet unsere Rundreise\"Example text\"。Jeden Tag wird ein neues Reiseziel angesteuert bis wir。
第二次编码再次转换它,转义已经转义的字符: 从:Heute startet unsere Rundreise \"Example text\"。Jeden Tag wird ein neues Reiseziel angesteuert bis wir。 到:Heute startet unsere Rundreise \\\\\"Example text\\\\\"。Jeden Tag wird ein neues Reiseziel angesteuert bis wir。
因此,如果您负责此处服务器的实现,请检查确保没有两个步骤试图对相同的内容进行编码。

7
我认为编码器也会转义转义开关,所以我认为你的第二个 TO: 应该写成:“今天我们的环游之旅开始了 \"Example text\"。每天都会到达一个新的旅游目的地,直到我们...” - Jonathan Mee
2
@Jonathan Mee:根据您的建议刚刚编辑了答案。理论上用3个反斜杠是正确的,但stackoverflow也使用反斜杠进行引用,并将前两个反斜杠转换为一个单独的反斜杠。 - huha

8
为了避免反斜杠对JSON数据造成问题,我使用这个函数。
//escape backslash to avoid errors
var escapeJSON = function(str) {
    return str.replace(/\\/g,'\\');
};

9
我会鼓励程序员对内容进行编码,而不是删除或"清洗"内容。过去有一种"清洗"数据库数据的想法,特别是删除单引号(')。程序员没有意识到人们无法使用自己的姓氏(如O'Doul)。我希望今天的程序员能够采用其他方式将原始内容输入数据库,而不是剥离或清洗数据。 - DanBaker
3
好的,我已经删除了字符剥离部分以迎合大众。@DanBaker 请记住,在客户端应用程序中剥离文本字符可能是使JS安全的唯一方法。出于这个原因,Angular默认会对HTML输出进行清理。 - mbokil
2
我完全同意有时需要对数据进行清理...而XSS就是其中之一。感谢您指出这一点。 - DanBaker

2

如果您想使用开发人员PowerShell,这里是要添加到您的settings.json文件中的代码:

"terminal.integrated.automationShell.windows": "C:\\Windows\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe",
"terminal.integrated.shellArgs.windows": [
    "-noe",
    "-c",
    " &{Import-Module 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\Tools\\Microsoft.VisualStudio.DevShell.dll'; Enter-VsDevShell b7c50c8d} ",
    ],

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接