如何用c风格的注释解析json文件?

Bol*_*ose 18 python json

我有一个json文件,如下所示:

    { 
       "author":"John",
       "desc": "If it is important to decode all valid JSON correctly \ 
and  speed isn't as important, you can use the built-in json module,   \
 orsimplejson.  They are basically the same but sometimes simplej \
further along than the version of it that is included with \
distribution."
       //"birthday": "nothing" //I comment this line
    }
Run Code Online (Sandbox Code Playgroud)

此文件由另一个程序自动创建.我如何用Python解析它?

小智 9

jsoncomment很好,但不支持内联注释.

查看jstyleson,哪个支持

  • 内联评论
  • 单行评论
  • 多行评论
  • 尾随逗号.

安装

pip install jstyleson

用法

import jstyleson
result_dict = jstyleson.loads(invalid_json_str) # OK
jstyleson.dumps(result_dict)
Run Code Online (Sandbox Code Playgroud)

  • 需要明确指出的是,您是“jstyleson”的作者。我认为这篇文章还可以,因为它是解决OP问题的一种方法,但除非明确指出,否则自我广告通常是不受欢迎的。 (15认同)

stu*_*eek 7

我没有亲自使用它,但是jsoncomment python 包支持解析带有注释的JSON文件。

您可以使用它代替 JSON 解析器,如下所示:

parser = JsonComment(json)
parsed_object = parser.loads(jsonString)
Run Code Online (Sandbox Code Playgroud)


Mit*_*ers 6

我建议大家改用 JSON5 库。JSON5 是具有 JavaScript 功能/支持的 JSON。它是世界上最流行的 JSON 语言扩展。它有注释,支持对象/数组中的尾随逗号,支持单引号键/字符串,支持不带引号的对象键等。并且有适当的解析器库和深度测试套件,一切正常。

有两种不同的高质量 Python 实现:

  • https://github.com/dpranke/pyjson5(完全用 Python 编写,速度很慢,有自己的测试套件,项目始于 2015 年,更“喜欢”)。PyPi 页面:https ://pypi.org/project/json5/

  • 推荐: https : //github.com/Kijewski/pyjson5(使用通过 Cython 编译的本地代码,速度更快,使用官方 json5 js 测试套件而不是自己的,项目于 2018 年启动)。PyPi 页面:https ://pypi.org/project/pyjson5/

这是 JSON5 规范:https ://json5.org/


Lou*_*ron 6

改进之前的答案,以便在删除行的情况下提供正确的行号支持:

import json

class JSONWithCommentsDecoder(json.JSONDecoder):
    def __init__(self, **kw):
        super().__init__(**kw)

    def decode(self, s: str) -> Any:
        s = '\n'.join(l if not l.lstrip().startswith('//') else '' for l in s.split('\n'))
        return super().decode(s)

your_obj = json.load(f, cls=JSONWithCommentsDecoder)
Run Code Online (Sandbox Code Playgroud)

此实现通过用空行替换注释行而不是完全删除它来稍微改进了前面的答案,因为这会破坏行数。


Ray*_*Luo 5

我无法想象一个json文件"由其他程序自动创建"将包含注释.因为json规范根本没有定义任何注释,这是设计的,所以没有json库会输出带注释的json文件.

这些评论通常是后来由人类添加的.在这种情况下也不例外.OP在他的帖子中提到://"birthday": "nothing" //I comment this line.

所以真正的问题应该是,如何正确评论json文件中的某些内容,同时保持其与规范的兼容性,从而与其他json库兼容?

答案是,将您的字段重命名为另一个名称.例:

{
    "foo": "content for foo",
    "bar": "content for bar"
}
Run Code Online (Sandbox Code Playgroud)

可以改成:

{
    "foo": "content for foo",
    "this_is_bar_but_been_commented_out": "content for bar"
}
Run Code Online (Sandbox Code Playgroud)

这在大多数情况下都会正常工作,因为消费者很可能会忽略意外字段(但并非总是如此,这取决于您的json文件使用者的实现.所以YMMV.)

更新:显然有些读者不高兴,因为这个答案没有给出他们期望的"解决方案".嗯,事实上,我确实提供了一个有效的解决方案,通过隐式链接到JSON设计师的引用:

Douglas Crockford Public 2012年4月30日评论JSON

我从JSON中删除了注释,因为我看到有人使用它们来保存解析指令,这种做法会破坏互操作性.我知道缺乏评论会让一些人感到悲伤,但事实并非如此.

假设您使用JSON来保留要注释的配置文件.继续,插入您喜欢的所有评论.然后通过JSMin将其传递给JSON解析器.

所以,是的,继续使用JSMin.请记住,当您前往"使用JSON中的注释"时,这是一个概念上未知的领域.无法保证您选择的任何工具都可以处理:内联[1,2,3,/* a comment */ 10],Python样式[1, 2, 3] # a comment(这是Python中的注释但不是Javascript中的注释),INI样式[1, 2, 3] ; a comment,......,您可以理解.

我仍然建议不要首先在JSON中添加不符合要求的注释.

  • 我真的无法忍受应该删除功能的心态,因为它们“可能”被滥用。正因为如此,我们现在有了过多的竞争性 JSON 替代品,因为纯 JSON 不支持常见且合理的用例。在我看来,预处理配置文件或必须“构建”配置并不是明智的方法,它只会增加阻抗。它使简单的事情变得困难,这与我们应该努力实现的目标相反。 (12认同)
  • 真的。应该指出的是,向 HTML 添加注释并没有阻止互操作性。您还可以通过尾随空格向解析器暗示,但这并不是不允许的。作为对人类作者的让步,空白是灵活的。我个人认为 JSON 介于两种标准之间:它是一种有线格式(不允许注释),但设计用于人类编辑(空白灵活)。我确实希望有一天能够达成一项允许评论的协议,但随后复杂的工具和库需要数年时间才能赶上。 (9认同)
  • “tsc --init”(打字稿)生成一个“tsconfig.json”,其中包含我相信的注释。 (4认同)
  • @RayLuo:我不希望这个评论部分变成无用的玩笑,所以:1)我添加了[我自己的答案,澄清了你选择不做的事情](/sf/answers/3960200611/)和2)至于“普遍同意”,我只想向您指出这些鲜为人知的代码编辑器:Sublime Text、Atom、VS Code(它们都使用 JSON 进行配置),然后就这样吧 (3认同)

小智 5

对于 [95%] 的情况,当您只需要简单的引导行//注释和简单的方法来处理它们时:

import json

class JSONWithCommentsDecoder(json.JSONDecoder):
    def __init__(self, **kw):
        super().__init__(**kw)

    def decode(self, s: str) -> Any:
        s = '\n'.join(l for l in s.split('\n') if not l.lstrip(' ').startswith('//'))
        return super().decode(s)

your_obj = json.load(f, cls=JSONWithCommentsDecoder)

Run Code Online (Sandbox Code Playgroud)