【问题标题】:Parsing string as JSON with single quotes?用单引号将字符串解析为 JSON?
【发布时间】:2016-07-02 11:55:23
【问题描述】:

我有一个字符串

str = "{'a':1}";
JSON.parse(str);
VM514:1 Uncaught SyntaxError: Unexpected token '(…)

如何将上述字符串 (str) 解析为 JSON 对象?

这似乎是一个简单的解析。但它不起作用。

【问题讨论】:

  • 单引号的 json 格式不正确,因此如果您收到类似的内容,您可能需要使用 str.replace() 并将单引号替换为 ",然后再尝试解析它
  • 无论如何,您都应该尝试在 javascript 中对字符串使用单引号。 var str = "bad example"; 不是好的做法,最好执行以下操作:var str = 'good example'; => 像这样您不会遇到 JSON 问题,也不会遇到 HTML 问题。 :)
  • @ReeCube 这似乎只是一种意见——HTML 无论如何都没有问题,它接受两者。对于 JSON,为什么还要用字符串创建它呢?我实际上不记得上次我用对象以外的任何东西构建 JSON 是什么时候了。

标签: javascript json


【解决方案1】:
// regex uses look-forwards and look-behinds to select only single-quotes that should be selected
const regex = /('(?=(,\s*')))|('(?=:))|((?<=([:,]\s*))')|((?<={)')|('(?=}))/g;
str = str.replace(regex, '"');
str = JSON.parse(str);

其他答案在足够多的情况下根本不起作用。比如上面引用的案例:"title": "Mama's Friend",除非你使用正则表达式,否则它会天真地转换撇号。 JSON5 将希望删除单引号,从而引入类似的问题。

警告:虽然我相信这适用于所有合理出现的情况,并且比其他答案更有效,但它仍然可以在理论上打破。

【讨论】:

  • ??????好
【解决方案2】:

如果您假设要显示单引号的值,则改为:

str = str.replace(/\'/g, '"');

你可以使用这个来保持单引号的显示:

str = str.replace(/\'/g, '\&apos;\');

这是single quote的HTML等价物。

【讨论】:

    【解决方案3】:

    如果您确定您的 JSON 安全在您的控制之下(不是用户输入),那么您可以简单地评估 JSON。 Eval 接受所有引号类型以及不带引号的属性名称。

    var str = "{'a':1}";
    var myObject = (0, eval)('(' + str + ')');
    

    由于 eval 解析器的工作方式,需要额外的括号。 当 Eval 用于您可以控制的数据时,它并不是邪恶的。 有关 JSON.parse 和 eval() 之间区别的更多信息,请参阅JSON.parse vs. eval()

    【讨论】:

    • 即使你认为 eval 在这种情况下并不邪恶,JSON.parse 总是更快:jsperf.com/json-parse-vs-eval/3
    • @Arkanoid 您链接到的基准不适用于这种情况,因为它仅使用有效的 JSON(由于 JSON.stringify)
    【解决方案4】:
    var str =  "{'a':1}";
    str = str.replace(/'/g, '"')
    obj = JSON.parse(str);
    console.log(obj);
    

    这解决了我的问题。

    【讨论】:

    • 这也会修改数据。 {'a':"A'A"} 将变为 {"a":"A"A"}
    【解决方案5】:
    json = ( new Function("return " + jsonString) )(); 
    

    【讨论】:

    • 请解释你的答案
    • 伙计们,永远不要这样做。这是超级不安全的
    • 使用Function 代替 eval 的原则是正确的,但其他一切都是错误的。应该是var json = Function("'use strict';return " + jsonString)()
    • 不要在此处获取 cmets。这可能是不安全的,在任何实现中都不是不安全的,就像许多 APIS 一样!。对我来说很有趣的是,这个答案得到了 10 多票反对,而带有 'eval' 的答案却以完全相同的方式“不安全”得到了 15 多票。当用户输入没有机会被评估时,根本没有风险!使用 Function 构造函数代替 'eval' 非常好,而且更优雅。
    【解决方案6】:

    我知道这是一篇旧帖子,但您可以使用 JSON5 来达到此目的。

    <script src="json5.js"></script>
    <script>JSON.stringify(JSON5.parse('{a:1}'))</script>
    

    【讨论】:

    • 赞成,因为上述解决方案将失败,例如:{'section': "24'"} 变为:{"section": "24""} 并且不会解析。
    • 这应该是最佳答案。
    • 完美解决方案。试图从 html 的脚本标记中抓取 JSON 字符串,其中包含换行符和空格。拯救了我的一天!
    • 对我来说这有效&lt;script&gt;JSON.stringify(some_jsonString)&lt;/script&gt;
    • 你将如何实现这个?我正在尝试使用 jsonlite 包读取 R 中的文件。
    【解决方案7】:

    类似这样的:

    var div = document.getElementById("result");
    
    var str = "{'a':1}";
      str = str.replace(/\'/g, '"');
      var parsed = JSON.parse(str);
      console.log(parsed);
      div.innerText = parsed.a;
    &lt;div id="result"&gt;&lt;/div&gt;

    【讨论】:

      【解决方案8】:

      JSON standard 需要双引号,不接受单引号,解析器也不接受。

      如果您的字符串中没有转义单引号的简单案例(这通常是不可能的,但这不是 JSON),您可以简单的 str.replace(/'/g, '"') 并且最终应该得到有效的 JSON。

      【讨论】:

      • 您的回答会篡改数据。一个好的答案会改变结构,而不是数据结构中的数据。
      • @ssube,用双引号全局替换单引号是第一个想到的方法,并且是一种草率的方法,因为它会破坏字典值。例如。 'title': "Mama's Friend"会变成"title": "Mama"s Friend",当然是无效的!我应该对您的回复投反对票,但我反对投反对票。这条评论更有价值。
      • 嗨@Apostolos 我同意你的观点,我现在面临同样的问题。你能找到解决办法吗?提前致谢
      • 是的,我找到了@Selvam 的解决方案,但这是很久以前的事了,但我不记得是什么了,因为这些天我很少使用 JSON 的东西。对不起! :(
      • 没问题。感谢您回复@Apostolos
      【解决方案9】:

      在 JSON 中不允许对键使用单引号。您需要使用双引号。

      对于您的用例,这可能是最简单的解决方案:

      str = '{"a":1}';
      

      Source:

      如果属性需要引号,则必须使用双引号。全部 属性名称必须用双引号括起来。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-21
        • 2020-06-26
        • 2012-07-19
        • 1970-01-01
        • 2019-10-22
        • 2018-12-14
        • 1970-01-01
        • 2011-03-14
        相关资源
        最近更新 更多