【问题标题】:How to escape special characters in building a JSON string?如何在构建 JSON 字符串时转义特殊字符?
【发布时间】:2013-10-11 03:28:50
【问题描述】:

这是我的字符串

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

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

【问题讨论】:

  • JSON 只使用双引号,不使用单引号,见json.org
  • RFC 4627 规定解析器必须能够解析符合标准的 JSON(第 4 段),并且可以支持其他非 JSON 扩展。但是,第 5 段强调所有生产者(生成者)必须只生成 100% 兼容的 JSON。使用不需要转义的帧字符生成 JSON 是一个特别糟糕的主意。请考虑用引号替换您的撇号。 ietf.org/rfc/rfc4627.txt
  • @Luv2code 虽然您提出的观点仍然正确,但请注意您引用的是过时的规范。阅读 RFC 时,请始终使用 tools.ietf.org/html 版本,而不是文本版本。 HTML 版本更易于阅读并链接到小节,最重要的是,HTML 版本的顶部是所有后续 RFC 的列表,这些 RFC 更新或废弃了您正在阅读的版本。如果您访问 tools.ietf.org/html/rfc4627,您会发现 RFC 4627 已过时并已被 RFC 7159 取代。
  • 对于未来阅读本文的人,RFC 7159 已被 tools.ietf.org/html/rfc8259 废弃

标签: json


【解决方案1】:

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

查看 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 字符串使用双引号。

【讨论】:

  • "单引号 json 字符串"?这是无稽之谈; JSON 中的字符串只能用双引号引起来。例如,在浏览器控制台中尝试JSON.parse("'foo'"),然后观察SyntaxError: Unexpected token '。 JSON 规范是 really simple and clear 关于这个。 JSON中没有单引号的转义序列,JSON字符串不能单引号。
  • 即使是对这个答案的所谓澄清更新也很糟糕。虽然在技术上是正确的,但说你“不需要” 来逃避' 是一种误导,就像在技术上是正确的但误导你说合法地不需要谋杀孩子。更正确的说法是你不能逃避'\' 是一个非法的转义序列,如果你使用它,那么你的 JSON 就是 not valid JSON 并且任何 JSON 解析器都会阻塞它。 (当然是 JavaScript 的 JSON.parse 和 Python 的 json.loads 做的。)
  • 经过多次编辑,这个答案仍然是一派胡言。您错误地声称,在 JSON 中使用单引号字符串并使用 \' 转义序列 “无论您是否想要它都有效”。这是错误的。我挑战你展示流行使用的任何 JSON 解析器,它不会在单引号字符串或\' 序列上阻塞。我已经指出JSON.parse("'foo'")JSON.parse('"\\\'"')(在JavaScript 中)和json.loads("'foo'")json.loads('"\\\'"')(在Python 中)都抛出异常。 您声称使用这些构造“有效”的依据是什么?
  • @Luv2code 有趣的报价。您稍微误解了它;它并不意味着任何字符都可以通过在其前面放置一个反斜杠来进行转义。更完整的引用是“任何字符都可以转义。如果字符在基本多语言平面(U+0000 到 U+FFFF)中,那么它可以表示为 六字符序列. ... 或者,一些流行的字符。“(强调我的)有两个字符的序列转义表示。它是说你可以将' 转义为\u0027不是你可以将它转义为\'
  • @Luv2code 仍然,这确实意味着我赞成的评论指出“你无法逃脱'”(并将这种行为与谋杀儿童进行比较!)在技术上是错误的;更准确的说法是你可以逃脱它,只是不像\'。我没有意识到规范的 RFC 版本提到了像\u0027 这样的序列作为“转义”它们所代表的字符的一种方式。不过,\' 非法的关键点仍然是真实且重要的。
【解决方案2】:

关于 AlexB 的帖子:

 \'  Apostrophe or single quote
 \"  Double quote

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

示例:

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

【讨论】:

  • 单引号字符串在 JSON 中是不合法的。 JSON 不是 JavaScript。 JSON 不允许转义单引号。有关 JSON 语法的非常简单的文档,请参阅 json.org
  • downvote - 因为单引号 jsons 无效!
  • 单引号在 json 中无效。如果可能,请展示一个工作示例
【解决方案3】:

每个人都在谈论如何在 ' 引用的字符串文字中转义 '。这里有一个更大的问题:单引号字符串文字不是有效的 JSON。 JSON 基于 JavaScript,但它不是一回事。如果您在 JavaScript 代码中编写对象字面量,那很好;如果你真的需要 JSON,你需要使用"

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

【讨论】:

  • 嗨,你说用双引号字符串,你不需要转义'。例如,如果我的字符串值为 "Member's_id" : 4 ,您是说它不需要转义吗?显然我遇到了一个问题,它给出了错误编码的错误:UTF-8,它被读取为Member�s。它是一个手动生成的 json 文件。
  • ' 在 JSON 字符串文字中不得转义。你是从某个地方复制粘贴的吗?也许它真的是\u2019,而不是撇号。我的猜测:有人将它输入到 MS Word 中,它把它变成了引号,因为它认为它最了解。从语法上讲,好的旧 ASCII 字符撇号(',a.k.a.\x27,到目前为止我们一直称之为“单引号”)是您想要的。但是如果还有其他类似的问题,修复您的字符编码问题仍然会很好。因此,选择一种字符编码,并将其用于读取和写入。或使用\u 转义。
【解决方案4】:

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

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

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

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

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

请注意,与此处其他一些答案中的废话相反,\' 绝不是 JSON 字符串中的有效转义序列。不需要,因为 JSON 字符串总是双引号。

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

【讨论】:

  • 4 个十六进制 字节nibbles
  • 我赞成这篇文章的暴躁。
【解决方案5】:

可能是我参加聚会为时已晚,但这会解析/转义单引号(不想在解析与转义方面陷入战斗)..

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

【讨论】:

    【解决方案6】:

    这些答案中的大多数要么没有回答问题,要么解释过于冗长。

    好的,所以 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 的答案很好

    希望这对某人有所帮助。

    【讨论】:

      【解决方案7】:

      回答直接问题:
      为安全起见,请将所需字符替换为 \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 的观点 - 感谢您成为论坛上的忍者。
      【解决方案8】:

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

      例如:

      var product_list = encodeURIComponent(JSON.stringify(product_list));
      

      您不需要对其进行解码,因为网络服务器会自动执行相同的操作。

      【讨论】:

      • 问题是关于在 JSON 中编码包含引号的字符串,而不是关于编码 JSON 以传递 URL。
      【解决方案9】:

      为了 json 的目的,为了允许在双引号字符串中使用单引号,请将单引号加倍。 {"X": "问题是什么"} ==> {"X": "问题是什么"}

      https://codereview.stackexchange.com/questions/69266/json-conversion-to-single-quotes

      \' 序列无效。

      【讨论】:

      • 在 JSON 字符串中加倍单引号不会对其进行转义。这只是意味着您的字符串包含两个单引号,而不是一个。
      • 您似乎将 JSON 与 SQL 混淆了。
      【解决方案10】:

      使用模板文字...

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

      【讨论】:

      • 这不会以任何方式解析或解码字符串。该字符串中也不包含 `\` 字符。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-02
      • 2013-09-08
      • 1970-01-01
      • 2016-01-27
      • 1970-01-01
      • 1970-01-01
      • 2011-05-11
      相关资源
      最近更新 更多