如何从json文件中删除某些注释?(/*)

2024-06-06 17:53:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我有大约500个json文件,其中包含注释。尝试使用新值更新json文件上的字段会引发错误。我设法使用commentjson删除了如下字符串//一些文本和json文件更新,并且没有抛出任何错误

但是大约有100个json文件有这样的注释:

  /*

   1. sometext.
        i. sometext
        ii. sometext 
   2. sometext

  */

当/*存在时,Commentjson就会崩溃。如果我删除/*并运行代码,它将工作并更新并删除任何//。 如何编写一些代码来管理/*和/**/之间的所有文本

这是我当前可以删除//的代码

with open(f"{i['Location']}\\{file_name}",'r') as f:
    json_info = commentjson.load(f) #Gets info from the json file
    json_info['password'] = password

    with open(f"{i['location_Daily']}\\{file_name}",'w') as f:
        commentjson.dump(json_info,f,indent = 4) #updates the password   
        print("updated")

Tags: 文件the代码name文本infojsonas
2条回答

您可以使用另一个库,如json5pyjson5,或任何支持JSON5的库

import json5
import pyjson5

data = '''
{
    "something": [
        ["any"],
        ["thing", "here", 10]    // This is comment 1
    ],
    /* While this
    is
    comment 2 */
    "car": [
        ["and", "another", "here"], /* Last comment */
    ]
}
'''

print(json5.loads(data))
print(pyjson5.loads(data))

输出

$ python3 script.py 
{'something': [['any'], ['thing', 'here', 10]], 'car': [['and', 'another', 'here']]}
{'something': [['any'], ['thing', 'here', 10]], 'car': [['and', 'another', 'here']]}

您有几个选择:

  • 将整个文件读入字符串,然后使用正则表达式预处理文本。例如:

    with open(...) as f:
        json_text = f.read()
    # remove everything from '/*' to '*/' as long as it is either
    # - a '*' character that is *not* followed by '/'
    # - any character that is not '*'
    without_comments = re.sub(r"/\*(?:\*(?!/)|[^*])*\*/", "", json_text)
    json_info = commentjson.loads(without_comments)
    

    请注意,如果JSON字符串中还有/**/两个字符,那么这种方法将不起作用。正则表达式不是JSON解析器

  • 尝试更新commonjson项目用于解析JSON的解析器。看一下the project source code,他们使用了Lark parsing library,因此您可以使用附加语法对模块进行修补

    我注意到主分支已经有了定义多行注释的语法规则:

    COMMENT: "/*" /(.|\\n)+?/ "*/"
           | /(#|\\/\\/)[^\\n]*/
    

    但这还不是他们释放的一部分。但是,您可以重复使用该规则:

    from commentjson import commentjson as implementation
    from lark.reconstruct import Reconstructor
    
    serialized = implementation.parser.serialize()
    for tok in serialized["parser"]["lexer_conf"]["tokens"]:
        if tok["name"] != "COMMENT":
            continue
        if tok["pattern"]["value"].startswith("(#|"):
            # only supports `#` or `//` comments, add block comments
            tok["pattern"]["value"] = r'(?:/\*(?:\*(?!/)|[^*])*\*/|(#|\/\/)[^\n]*)'
        break
    
    implementation.parser = implementation.parser.deserialize(serialized, None, None)
    

    我在语法更新中使用了自己的正则表达式,而不是项目使用的版本

  • 查找其他库以解析输入。有几个选项声称支持使用相同语法解析JSON:

    我没有尝试过这些,也没有对它们的可用性或性能发表任何意见

相关问题 更多 >