【问题标题】:Read json file ignoring custom comments读取 json 文件忽略自定义注释
【发布时间】:2017-04-02 18:54:04
【问题描述】:

我如何阅读这个文件'file.json':

# Comment01
# Comment02
{
   "name": "MyName"
}

并在没有 cmets 的情况下检索 json?

我正在使用此代码:

var fs = require('fs');
var obj;
fs.readFile('./file.json', 'utf8', function (err, data) { 
  if (err) throw err;
  obj = JSON.parse(data);
});

它返回此错误:

SyntaxError: Unexpected token # in JSON at position 0

npm 一些软件包来解决这个问题吗?

【问题讨论】:

    标签: json node.js npm readfile


    【解决方案1】:

    您要查找的包名为 strip-json-cmets - https://github.com/sindresorhus/strip-json-comments

    const json = '{/*rainbows*/"unicorn":"cake"}';
    
    JSON.parse(stripJsonComments(json)); //=> {unicorn: 'cake'}
    

    【讨论】:

    • 但是在这个包中我可以将我的自定义评论定义为#?
    • 看看这个包是如何处理常规 cmets 的,它应该给你一个处理自定义 cmets 的想法
    • 我提交了一个问题! github.com/sindresorhus/strip-json-comments/issues/31 创建者在插件中修复此解决方案。
    • 作者拒绝了我的问题请求,但建议使用此包使用“#”字符作为评论。 npmjs.com/package/hjson
    【解决方案2】:

    您可以很容易地使用自己的RegExp 来匹配以# 开头的 cmets

    const matchHashComment = new RegExp(/(#.*)/, 'gi');
    const fs = require('fs');
    
    fs.readFile('./file.json', (err, data) => {
        // replaces all hash comments & trim the resulting string
        let json = data.toString('utf8').replace(matchHashComment, '').trim();  
        json = JSON.parse(json);
        console.log(json);
    });
    

    【讨论】:

    • 是的,它有效,但我已将正则表达式调整为:/#.*/,因为如果只有一个 # 它不起作用。谢谢!
    【解决方案3】:

    这个问题的完美包是https://www.npmjs.com/package/hjson

    hjson文本输入:

    
    {
      # hash style comments
      # (because it's just one character)
    
      // line style comments
      // (because it's like C/JavaScript/...)
    
      /* block style comments because
         it allows you to comment out a block */
    
      # Everything you do in comments,
      # stays in comments ;-}
    }
    

    用法:

    var Hjson = require('hjson');
    
    var obj = Hjson.parse(hjsonText);
    var text2 = Hjson.stringify(obj);
    

    【讨论】:

      【解决方案4】:

      NPM 上有替代包:json-easy-strip 主要思想是只使用单行 RegExp 来剥离所有类型的 JS 风格的 cmets。是的,这很简单而且很有可能!包更高级,有一些文件缓存等,但仍然很简单。这是核心:

      sweet.json

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

      index.js

      const fs = require('fs');
      const data = (fs.readFileSync('./sweet.json')).toString();
      
      // Striper core intelligent RegExp.
      // The idea is to match data in quotes and
      // group JS-type comments, which is not in
      // quotes. Then return nothing if there is
      // a group, else return matched data.
      const json = JSON.parse(data.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (m, g) => g ? "" : m));
      
      console.log(json);
      
      //  {
      //    fruit: 'Watermelon',
      //    dessert: 'Cheesecake',
      //    drink: 'Milkshake - /* strawberry */ or // chocolate!'
      //  }
      

      现在是因为您询问的是 ShellScripting 样式的 cmets

      #
      # comments
      #
      

      我们可以通过在其末尾添加\#.* 来扩展我们的正则表达式:

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

      或者,如果你根本不想要 JS 风格的 cmets:

      const json = JSON.parse(data.replace(/\\"|"(?:\\"|[^"])*"|(\#.*)/g, (m, g) => g ? "" : m));
      

      【讨论】:

        【解决方案5】:

        Javascript 有一个内置的评论删除器,不需要额外的包。不过,我不会为用户输入这样做。

        eval(
          'var myjsonfile=' +
            require('fs')
              .readFileSync('./myjsonfile.json')
              .toString(),
        );
        console.log(myjsonfile);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-12-22
          • 2012-10-29
          • 1970-01-01
          • 2015-09-15
          • 2016-10-31
          • 1970-01-01
          • 2022-01-04
          • 1970-01-01
          相关资源
          最近更新 更多