【问题标题】:how to strip json comments in javascript如何在 javascript 中去除 json 注释
【发布时间】:2016-02-02 16:38:30
【问题描述】:

如何在 javascript 中剥离 json cmets ? 我认为正则表达式将是一种简洁的方式。

{
    "filed": { // comments
         "n": 1 /* multi-line ...
                                 comments */
    },
    "field2": " // comments in string , /* here */ "
}

应该在上面的例子中工作。
注意:字符串中的 cmets 应该被删除。

更新:我知道 cmets i json 无效,但为简单起见,我想拥有它们然后删除它们,我看到很多工具支持解析具有 cmets 的 json。

更新 2:上面的例子本身是一个字符串,我没有解释(对不起),现在看到一些答案认为它是一个 js 代码。

更新 3:我再次忘记将键名放在双引号中,更新了问题。

【问题讨论】:

  • 为什么在 json 中有 cmets?那个json无效...
  • 更新了问题@taxicala
  • 如果你想走正则表达式路线,(\/\*[\S\s]*?\*\/)|(\/\/[^\n]*) 可能工作:regex101.com/r/fJ1aC6/1
  • 带或不带 cmets - 它是不是 JSON,它是一个对象字面量。
  • 我刚刚为此写了一个小帮手:decomment.

标签: javascript json regex


【解决方案1】:

虽然在 JSON 中注释不是标准做法,但在某些情况下它可能很有用。为此我为nodejs写了一个小包:json-easy-strip

这是它的主要源代码:

数据

{
    /*
     * Sweet section
     */
    "fruit": "Watermelon", // Yes, watermelons is sweet!
    "dessert": /* Yummy! */ "Cheesecake",
    // And finally
    "drink": "Milkshake - /* strawberry */ or // chocolate!" // Mmm...
}

单行解析器

data = data.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (m, g) => g ? "" : m);

结果

console.log(data);

//  {
//    fruit: 'Watermelon',
//    dessert: 'Cheesecake',
//    drink: 'Milkshake - /* strawberry */ or // chocolate!'
//  }

这里是demo

【讨论】:

    【解决方案2】:

    一种简单的方法是运行JSON.stringify,然后运行JSON.parse,瞧,它是干净的。

    【讨论】:

    • 如果您的 JSON 更像 JavaScript 或 JSON5,​​那么它就不起作用,即 JSON 使用开放名称属性或值的正则表达式。
    【解决方案3】:

    让 javascript 解析器来做:

    a = {
        filed: { // comments
             n: 1 /* multi-line ...
                                     comments */
        },
        field2: " // comments in string , /* here */ "
    }
    a.toSource()
    /*
    ({filed:{n:1}, field2:" // comments in string , /* here */ "})
    */
    

    你可以用一个字符串(根据编辑的问题)以同样的方式来做:

    a =   'a = {\r\n  filed: { // comments  n: 1 \r\n/* multi-line ...  comments */\r\n},\r\n'
        + 'field2: " // comments in string , /* here */ "\r\n}'
    eval(a).toSource().toString();
    

    但它似乎不适用于 chrome?哦,忘了,它只是 FF,抱歉(在 Javascript 版本 3 中)。

    我在https://gist.github.com/archan937/1961799 找到了替代品,因此以下内容也适用于大多数其他浏览器。

    function inspect(object) {
      switch (typeof(object)) {
      case "undefined":
        return "undefined";
      case "string":
        return "\"" + object.replace(/\n/g, "\\n").replace(/\"/g, "\\\"") + "\"";
      case "object":
        if (object == null) {
          return "null";
        }
        var a = [];
        if (object instanceof Array) {
          for (var i in object) {
            a.push(inspect(object[i]));
          };
          return "[" + a.join(", ") + "]";
        } else {
          for (var key in object) {
            if (object.hasOwnProperty(key)) {
              a.push(key + ": " + inspect(object[key]));
            }
          };
          return "{" + a.join(", ") + "}";
        }
      default:
        return object.toString();
      }
    };
    
    a = 'a = {\r\n  filed: { // comments  n: 1 \r\n/* multi-line ...  comments */\r\n},\r\n'
        + 'field2: " // comments in string , /* here */ "\r\n}'
    
    alert(inspect(eval(a)));
    

    【讨论】:

      【解决方案4】:

      如果您需要删除支持 JSON5 的 cmets,请查看库 decomment

      它可以以同样简单的方式从 JSON5、JavaScript ES6、CSS 和 HTML 中删除 cmets。

      var decomment = require('decomment');
      
      var code = "var t; // comments";
      
      decomment(code); //=> var t;
      

      【讨论】:

        【解决方案5】:

        只是个人意见,如果您想保留一个充满 cmets 的无效 JSON 用于生产目的,我想这取决于您,但是将这些东西部署到您的实时网站,然后用 JavaScript hack 填充它以使其工作并没有一点都不好看我建议您生成一个干净的 JSON 文件进行部署,并将注释代码留给自己。最终用户不必看到这一点,他当然也不需要一堆缩进空格来增加传输的数据量。

        无论如何,这是删除这些 cmets 的一种方法:

        var invalid_json = "{\n\"filed\": { // comments\n\"n\": 1 /* multi-line ...\ncomments */\n},\n\"field2\": \" // comments in string , /* here */ \"\n}";
        
        eval("var x = " + invalid_json);
        var x = JSON.stringify(x);
        alert(x); // x should be valid JSON of that
        

        另一种方法是将其用作 JavaScript 而不是 JSON,您只需稍微修改文件:

        // file.js
        var data = {
            "filed": { // comments
                 "n": 1 /* multi-line ...
                                         comments */
            },
            "field2": " // comments in string , /* here */ "
        };
        

        在页面中:

        <script type="text/javascript" src="file.js"></script>
        

        这应该会将名为 data 的对象导入您的页面。

        【讨论】:

        • 只是我的看法:当你说“为部署生成一个干净的 JSON 文件”时——这会增加已经很复杂的构建工具的复杂性,并且随着构建工具的升级需要维护。对我来说,如果它让事情变得简单,那么抛出一些额外的字节并没有什么坏处。 +感谢eval hack,完美运行!
        猜你喜欢
        • 2019-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-15
        • 1970-01-01
        • 1970-01-01
        • 2013-06-25
        • 1970-01-01
        相关资源
        最近更新 更多