json.loads能否忽略多余的逗号?

54 投票
8 回答
28438 浏览
提问于 2025-04-18 06:49

这个StackOverflow问题中提到,JSON格式中是不允许有多余的逗号的。比如,这段代码

{
    "key1": "value1",
    "key2": "value2"
}

是正确的,但这段代码

{
    "key1": "value1",
    "key2": "value2",
}

就不符合语法规则。

而在另一个StackOverflow问题中提到的原因是,在Python代码中使用多余的逗号是合法的(甚至可能是被鼓励的?)。我同时在使用Python和JSON,所以我希望在这两种文件中保持一致性。有没有办法让json.loads忽略多余的逗号呢?

8 个回答

5

python-rapidjson 解决问题很简单:

(这特别适合在 VSCode 的 settings.json 或类似文件上进行脚本编写,因为这些文件经常会生成或容忍无效的 JSON、JSON 中的注释等。)

import rapidjson

# From string: use rapidjson.loads
rapidjson.loads(
    raw_string, parse_mode=rapidjson.PM_COMMENTS | rapidjson.PM_TRAILING_COMMAS
)

# From file: use rapidjson.load
rapidjson.load(
    "file.json", parse_mode=rapidjson.PM_COMMENTS | rapidjson.PM_TRAILING_COMMAS
)
8

在传递这个值之前,先把逗号去掉。

import re

def clean_json(string):
    string = re.sub(",[ \t\r\n]+}", "}", string)
    string = re.sub(",[ \t\r\n]+\]", "]", string)

    return string
10

在Python中,你可以在字典和列表的末尾加上逗号,所以我们可以利用这个特性来使用ast.literal_eval

import ast, json

str = '{"key1": "value1", "key2": "value2",}'

python_obj = ast.literal_eval(str) 
# python_obj is {'key1': 'value1', 'key2': 'value2'}

json_str = json.dumps(python_obj)
# json_str is '{"key1": "value1", "key2": "value2"}'

不过,JSON并不完全等同于Python,所以有一些特殊情况需要注意。例如,像null、true、false这样的值在Python中是不存在的。我们可以在执行eval之前,把这些值替换成Python中有效的对应值:

import ast, json

def clean_json(str):
  str = str.replace('null', 'None').replace('true', 'True').replace('false', 'False')
  return json.dumps(ast.literal_eval(str))

不过,这样做会不幸地把任何包含null、true或false这些词的字符串搞混。

{"sentence": "show your true colors"} 

会变成

{"sentence": "show your True colors"}
20

快进到2021年,现在我们有了https://pypi.org/project/json5/

以下是链接中的一句话:

这是一个Python实现的JSON5数据格式。

JSON5在JSON数据交换格式的基础上进行了扩展,使其作为配置语言时更易用:

  • 支持JavaScript风格的注释(包括单行和多行注释)。
  • 对象的键可以不加引号,只要它们是合法的ECMAScript标识符。
  • 对象和数组可以以逗号结尾。
  • 字符串可以用单引号包裹,并且支持多行字符串。

使用方法和Python自带的json模块一致:

>>> import json5
>>> json5.loads('{"key1": "{my special value,}",}')
{u'key1': u'{my special value,}'}

不过它有个警告:

已知问题

  • 我提到过它很慢吗?

不过对于加载启动配置等来说,它的速度还是够用的。

10

你可以用 jsoncomment 来包装 Python 的 JSON 解析器。

JSON Comment 允许你解析 JSON 文件或字符串,支持以下功能:

  • 单行和多行注释
  • 多行数据字符串
  • 在对象和数组的最后一个项目后面可以有多余的逗号

使用示例:

import json
from jsoncomment import JsonComment

with open(filename) as data_file:    
    parser = JsonComment(json)
    data = parser.load(data_file)

撰写回答