【问题标题】:Python can't parse JSON with extra trailing commaPython 无法解析带有额外尾随逗号的 JSON
【发布时间】:2019-03-09 06:18:42
【问题描述】:

这段代码:

import json
s = '{ "key1": "value1", "key2": "value2", }'
json.loads(s)

在 Python 2 中产生此错误:

ValueError:预期属性名称:第 1 行第 16 列(字符 15)

Python 3 中的类似结果:

json.decoder.JSONDecodeError: 期望用双引号括起来的属性名称:第 1 行第 16 列 (char 15)

如果我删除那个尾随逗号(在"value2" 之后),我不会收到任何错误。但是我的代码会处理很多不同的 JSON,所以我不能手动完成。是否可以将解析器设置为忽略最后的逗号?

【问题讨论】:

  • 您无法修复源以生成有效的 JSON?
  • @Kingsley 这是用于在线控制台中的用户输入。当 JSON 字典中有很多记录并且您删除最后一条记录时,您会得到一个尾随逗号并且很容易忘记它......所以,最好将这些小事情自动化。

标签: python json parsing runtime-error


【解决方案1】:

另一种选择是将其解析为 YAML; YAML 接受有效的 JSON,但也接受各种变体。

import yaml
s = '{ "key1": "value1", "key2": "value2", }'
yaml.load(s)

【讨论】:

  • 哇,这太简单了,太棒了,谢谢!我只是说 YAML 是 JSON 的超集。还应该提到的是,YAML 解析要慢得多,但它适用于罕见的用户输入解析。
  • Yaml 并非没有问题,不过 - 我最好建议您使用 JSON5 库来避免像挪威问题、空白地狱等陷阱......
  • @exyi 链接:The Norway Problem
【解决方案2】:

JSON 规范不允许尾随逗号。解析器正在抛出,因为它遇到了无效的语法标记。

您可能有兴趣为这些文件使用不同的解析器,例如。为JSON5 spec 构建的解析器,它允许这样的语法。

【讨论】:

  • 谢谢!事实上,我正在为 JSON 的超集寻找这样的解析器。
【解决方案3】:

这个数据流可能是JSON5,在这种情况下有一个解析器:https://pypi.org/project/json5/

这种情况可以通过查找", } 并将其替换为" } 的正则表达式替换来缓解,从而允许引号、逗号和右大括号之间有任意数量的空格。

>>> import re
>>> s = '{ "key1": "value1", "key2": "value2", }'
>>> re.sub(r"\"\s*,\s*\}", "\" }", s)
'{ "key1": "value1", "key2": "value2" }'

给予:

>>> import json
>>> s2 = re.sub(r"\"\s*,\s*\}", "\" }", s)
>>> json.loads(s2)
{'key1': 'value1', 'key2': 'value2'}

编辑:正如评论的那样,这不是一个好习惯,除非您确信您的 JSON 数据仅包含简单的单词,并且此更改不会进一步破坏数据流。正如我对 OP 的评论,最好的做法是修复上游数据源。但有时这是不可能的。

【讨论】:

  • 您不应该使用正则表达式来解析 JSON。这个“解决方案”可以改变数据,例如。 JSON 可以包含一个字符串 ", }"
【解决方案4】:

这是因为根据JSON standard,额外的,无效。

对象是一组无序的名称/值对。一个对象开始 带有 {(左大括号)并以 }(右大括号)结尾。每个名字都是 后跟 :(冒号),名称/值对由 , 分隔 (逗号)。

如果你真的需要这个,你可以用jsoncomment包装python的json解析器。但我会尝试在源中修复 JSON。

【讨论】:

  • 这很明显 :) 但无论如何都需要处理这些错误的 JSON。在我看来,这应该是一个简单的解决方案的热门问题。
  • 我见过 jsoncomment,据我所知它使用正则表达式并破坏带有嵌套特定符号的字符串。我的意思是,它会在这里删除值字符串中的逗号:'{"foo": ",}"}'
【解决方案5】:

我怀疑它不会解析,因为“它不是 json”,但您可以预处理字符串,使用正则表达式将 , } 替换为 }, ] 替换为 ]

【讨论】:

  • 没错,但是这样的预处理会破坏带有这些符号的字符串。考虑这个例子:'{"foo": ",}"}'
  • 正确,如果这是预期的输入。
  • 没错。不要使用正则表达式解析 HTML,不要使用正则表达式解析 JSON。您正在寻找的是 JSON 的扩展语言,即 JSON5。您的文件是用 JSON5 编写的,因此只需使用解析器即可。
【解决方案6】:

使用下面的正则表达式怎么样?

s = re.sub(r",\s*}", "}", s)

【讨论】:

  • 这将主要工作,但这样的预处理会破坏带有特定符号的字符串。考虑这个例子:'{"foo": ",}"}'
  • @AivanF。你说的对。但基本上你面临着无效的 JSON。我认为不会有完美的解决方案。
  • 我确定是 :) JavaScript 和 Python 解析尾随逗号没有任何问题,因此,它只取决于解析器。 Lazar 建议使用 JSON5 解析器,我认为这是最好的选择。
  • JSON5 是一个超集,这意味着从 JSON5 生成的字符串可能与 JSON 不兼容。无论如何,这取决于你的情况。如果只需要解析,我觉得还可以。
猜你喜欢
  • 2012-06-18
  • 1970-01-01
  • 2016-10-24
  • 2020-02-06
  • 1970-01-01
  • 1970-01-01
  • 2022-06-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多