如何在构建JSON字符串时转义特殊字符?


200

这是我的绳子

{
    'user': {
        'name': 'abc',
        'fx': {
            'message': {
                'color': 'red'
            },
            'user': {
                'color': 'blue'
            }
        }
    },
    'timestamp': '2013-10-04T08: 10: 41+0100',
    'message': 'I'mABC..',
    'nanotime': '19993363098581330'
}    

此处,消息包含单引号,与JSON中使用的引号相同。我要做的是从用户输入(例如消息)中填充一个字符串。因此,我需要避免那些破坏代码的特殊情况。但是,除了字符串替换之外,还有什么方法可以使它们转义,但仍然允许HTML将其处理回正确的消息?


45
JSON仅使用双引号,而不使用单引号,请参阅json.org
Niels Bom

4
RFC 4627声明解析器必须能够解析符合JSON(第4段),并且可能支持其他非JSON扩展。但是,第5段着重指出,所有生产者(生成器)必须只生产100%兼容的JSON。用不需要转义的框架字符生成JSON是一个特别糟糕的主意。请考虑将引号替换为引号。ietf.org/rfc/rfc4627.txt
Luv2code

3
@ Luv2code当您提出要点时,请注意,您引用的是过时的规范。阅读RFC时,请始终使用tools.ietf.org/html版本,而不是文本版本。HTML版本更易于阅读并链接到其子部分,最重要的是,HTML版本的顶部是所有后续RFC的列表,这些RFC更新或废弃了正在阅读的RFC。如果您转到tools.ietf.org/html/rfc4627,您会发现RFC 4627已过时,并已由RFC 7159取代。
Mark Amery

3
对于人们在将来读这篇文章,RFC 7159现在已经被废弃的tools.ietf.org/html/rfc8259
约兰范登Boezem

Answers:


286

根据规范,JSON字符串必须用双引号引起来,因此您无需逸出'
如果必须在JSON字符串中使用特殊字符,则可以使用\character 对其进行转义。

请参阅此JSON中使用的特殊字符列表:

\b  Backspace (ascii code 08)
\f  Form feed (ascii code 0C)
\n  New line
\r  Carriage return
\t  Tab
\"  Double quote
\\  Backslash character


但是,即使完全违反规范,作者也可以使用\'

这很糟糕,因为:

  • 这与规格相反
  • 它不再是JSON有效字符串

但是,不管您想要与否,它都可以工作。

对于新读者,请始终对json字符串使用双引号。


30
“单引号的json字符串”?这是无稽之谈; JSON中的字符串只能双引号。JSON.parse("'foo'")例如,在浏览器控制台中尝试并观察SyntaxError: Unexpected token '。JSON规范非常简单,对此很清楚。JSON中没有单引号的转义序列,并且JSON字符串不能单引号。
Mark Amery 2014年

15
甚至据说这个答案的澄清更新也是不好的。尽管从技术上讲是正确的,但说您“不需要”逃脱'是一种误导,这与从技术上讲是正确的,但是在法律上说您不需要谋杀儿童的误导。更正确的说法是说你无法逃脱'\'是一个非法的转义序列,如果使用它,那么您的JSON是无效的JSON,并且任何JSON解析器都将对其阻塞。(当然是JavaScript JSON.parse和Python的json.loads。)
Mark Amery 2015年

2
经过多次编辑后,该答案仍然毫无意义。您错误地宣称,在JSON中使用单引号字符串并使用\'转义序列“可以根据需要使用或不起作用”。这是错误的。我要求您展示任何流行的JSON解析器,这些解析器不会使单引号字符串或\'序列阻塞。我已经指出,JSON.parse("'foo'")and JSON.parse('"\\\'"') (在JavaScript中)和json.loads("'foo'")and json.loads('"\\\'"')(在Python中)都抛出异常。声称使用这些构造“有效”的依据是什么呢?
Mark Amery

10
@ Luv2code有趣的报价。您会误解它;这并不意味着任何字符都可以通过在其前面加上反斜杠来转义。更完整的引用是“任何字符都可以转义。如果该字符在基本多语言平面中(U + 0000到U + FFFF),则可以表示为六个字符的序列。...或者,有两个- 一些流行字符的字符序列转义表示 ”(强调我)。意思是您可以'按来逃避\u0027而不是可以按来逃避\'
Mark Amery 2015年

2
@ Luv2code仍然是,这确实意味着我赞成的评论指出“您无法逃脱'”(并将这种行为与谋杀儿童相提并论!)在技术上是错误的;更准确地说是您可以逃脱它,而不是那样\'。我还没有意识到规范的RFC版本将序列\u0027称为“转义”它们代表的字符的方式。\'但是,非法的要点仍然是真实且重要的。
马克·阿默里

361

对于这样一个关于基本主题的备受关注的问题,存在高度支持的错误信息,我感到震惊。

JSON字符串不能用单引号引起来。规范的各种版本(Douglas Crockford 最初使用的版本ECMA版本IETF版本)都声明必须用双引号将字符串引起来。这不是理论问题,也不是目前公认的答案所引起的见解。如果您尝试让它解析单引号字符串,那么现实世界中的任何JSON解析器都会出错。

Crockford和ECMA的版本甚至使用漂亮的图片显示了字符串的定义,这应该清楚地说明这一点:

该图显示了JSON规范中字符串的定义

漂亮图片还列出了JSON字符串中的所有合法转义序列:

  • \"
  • \\
  • \/
  • \b
  • \f
  • \n
  • \r
  • \t
  • \u 后跟四个十六进制数字

请注意,与这里其他一些答案中的废话相反,\'它从来不是JSON字符串中的有效转义序列。不需要这样,因为JSON字符串始终被双引号引起来。

最后,在以编程方式生成JSON 时,您通常不必考虑自己转义字符(尽管在手动编辑(例如,基于JSON的配置文件时)当然会进行转义)。而是使用您的语言具有的任何本机映射,数组,字符串,数字,布尔值和null类型来形成要编码的数据结构,然后使用JSON编码功能将其编码为JSON。无论您使用哪种语言(例如JavaScript JSON.stringify,PHP json_encode或Python),都可以内置此函数json.dumps。如果您使用的语言没有内置此类功能,则可能会找到要使用的JSON解析和编码库。如果仅使用语言或库函数来将事物与JSON相互转换,您甚至不需要知道JSON的转义规则。这就是在此误导的提问者应该做的事情。


4个十六进制字节还是半字节
leetbacoon

36

每个人都在谈论如何'在带'引号的字符串文字中进行转义。这里有一个更大的问题:单引号字符串文字不是有效的JSON。JSON基于JavaScript,但这不是一回事。如果要在JavaScript代码中编写对象文字,可以;如果您确实需要JSON,则需要使用"

使用双引号引起来的字符串,您无需转义'。(如果您确实希望"在字符串中使用文字,则可以使用\"。)


1
嗨,您说过用双引号引起来的字符串,您无需转义'。敌人的例子,如果我的字符串值为"Member's_id" : 4,您是说不需要转义吗?显然我遇到了一个问题,即它给出了错误的编码错误:UTF-8,并且被读取为Member�s。它是一个手动生成的json文件。
Shubham

1
'JSON字符串文字中的Escape不能转义。您是否从某个地方复制粘贴了它?也许实际上是\u2019一个撇号,而不是撇号。我的猜测:有人在MS Word中输入了它,然后将它变成了引号,因为它认为它最了解。在语法上,您想要的是老式的ASCII字符撇号(',又名\x27,我们一直将其称为“单引号”)。但是,如果还有其他类似的问题,修复字符编码问题还是不错的。因此,请选择一种字符编码,并将其用于读取和写入。或使用逃脱\u
David Knipe

7

这些答案中的大多数要么不回答问题,要么在解释上不必要地冗长。

OK,所以JSON仅使用双引号,我们明白了!

我试图使用JQuery AJAX将JSON数据发布到服务器,然后稍后返回相同的信息。我发现的已发布问题的最佳解决方案是使用:

var d = {
    name: 'whatever',
    address: 'whatever',
    DOB: '01/01/2001'
}
$.ajax({
    type: "POST",
    url: 'some/url',
    dataType: 'json',
    data: JSON.stringify(d),
    ...
}

这将为您转义字符。

马克·埃默里(Mark Amery)的建议也不错,BTW

希望这对某人有帮助。


0

可能我参加聚会太迟了,但这将解析/转义单引号(不想陷入解析vs逃脱之战)。

JSON.parse("\"'\"")

0

回答直接问题:
为安全起见,请用\ u + 4-digit-hex-value替换所需的字符

示例:如果要转义撇号',请替换为
\ u0027 D'Amico变为D \ u0027Amico

不错的参考:http : //es5.github.io/x7.html#x7.8.4

https://mathiasbynens.be/notes/javascript-escapes


-1为参考。问题是关于JSON的,但您的链接引用是关于JavaScript的,列出了在JavaScript中无效的转义序列,例如\'
马克·阿默里

谢谢马克-我真的只是想提出一个替代的角度-取决于谁到达这里可能会觉得有用。但是,我同意JSON和Javascript的观点-感谢您成为论坛中的Ninja。
路易吉·达米科

0

使用encodeURIComponent()对字符串进行编码。

例如。var product_list = encodeURIComponent(JSON.stringify(product_list));

您不需要解码它,因为Web服务器会自动执行相同的操作。


0

使用模板文字...

var json = `{"1440167924916":{"id":1440167924916,"type":"text","content":"It's a test!"}}`;

-2

我认为我们都同意单引号json不是真正的json。即便如此,我们仍然需要解决在没有库的情况下在双引号json字符串中转义“”的问题。

用“ \”代替每个“”是不够的:用户可以输入输入:\,并且再次解析失败(请思考为什么)。

而是先将每个\替换为\(双反斜杠)。只有这样,才能将每个“替换为\”(反斜杠后跟“”)。


-2

为了允许将双引号引起来的双引号用于json,请将双引号加倍。{“ X”:“问题是什么”} ==> {“ X”:“问题是什么”}

/codereview/69266/json-conversion-to-single-quotes

\'序列无效。


2
将JSON字符串中的单引号加倍不会逃脱它。这仅表示您的字符串包含两个单引号而不是一个引号。
Mark Amery

-15

关于AlexB的帖子:

 \'  Apostrophe or single quote
 \"  Double quote

转义单引号仅在单引号的json字符串中
有效转义双引号仅在双引号的json字符串中有效

例:

'Bart\'s car'       -> valid
'Bart says \"Hi\"'  -> invalid

14
单引号字符串在JSON中不合法。JSON不是javascript。JSON不允许转义单引号。有关JSON语法的非常简单的文档,请参见json.org
srm 2014年

3
downvote-因为单引号json是无效的!
DominikAngerer 2015年

单引号在json中无效。如果可能的话,请显示工作示例
Rohith
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.