如何在 javascript 中去除 json 注释

Posted

技术标签:

【中文标题】如何在 javascript 中去除 json 注释【英文标题】:how to strip json comments in javascript 【发布时间】: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. 【参考方案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,完美运行!

以上是关于如何在 javascript 中去除 json 注释的主要内容,如果未能解决你的问题,请参考以下文章

spring mvc强制返回类型为json时怎么去除前后的双引号

javascript 中如何判断是否是JSON格式的字符串

关于如何去除数组中重复项

JS数组去重的方法汇总

Javascript JSON 的问题

javascript去除字符串里面的小括号