【问题标题】:How to correct leading zeroes in JSON with python如何使用python纠正JSON中的前导零
【发布时间】:2020-09-29 04:07:15
【问题描述】:

我有一个格式错误的 JSON 文件,其中的数字带有前导零。

p = """[
{
    "name": "Alice",
    "RegisterNumber": 911100020001
},
{
    "name": "Bob",
    "RegisterNumber": 000111110300
}
]"""
arc = json.loads(p)

我收到此错误。

JSONDecodeError: 需要 ',' 分隔符:第 8 行第 24 列(字符 107)

这是 char 107 上的内容:

print(p[107])
#0

问题是:这是我拥有的数据。这里我只展示两个例子,但是我的文件有数百万行要解析,我需要一个脚本。归根结底,我需要这个字符串:

"""[
{
    "name": "Alice",
    "RegisterNumber": "911100020001"
},
{
    "name": "Bob",
    "RegisterNumber": "000111110300"
}
]"""

我该怎么做?

【问题讨论】:

  • 错误消息指出错误在哪里,前导零不是问题。
  • 提示:根据错误消息,需要逗号分隔符。
  • 我用新的可运行代码更新了代码,但错误仍然存​​在。
  • @lispguy,你忘了提新的错误信息..
  • 哇,这在 java 中解析甚至很危险,因为它可能被解释为八进制数(由于前导零)。然后将其解释为十进制数字并简单地用零填充会弄乱寄存器编号。

标签: python json


【解决方案1】:

读取文件(最好逐行)并用它们的字符串表示替换所有值。您可以为此使用正则表达式 (remodule)。 然后保存并稍后解析有效的 json。

如果它适合内存,您当然不需要保存文件,只需保存loads 即有效的json 字符串。

这是一个简单的版本:

import json

p = """[
{
    "name": "Alice",
    "RegisterNumber": 911100020001
},
{
    "name": "Bob",
    "RegisterNumber": 000111110300
}
]"""

from re import sub
p = sub(r"(\d{12})", "\"\\1\"", p)

arc = json.loads(p)
print(arc[1])

【讨论】:

  • 如果密钥名称包含 12 位数字怎么办?
  • 我的解决方案假定输入由 lispguy 给出。 Loïc Faure-Lacroix 的答案更适用于更一般的情况,即 12 位数字可能出现在其他地方。
【解决方案2】:

这可能不会很漂亮,但您可以使用正则表达式来解决这个问题。

import re
p = "..."
sub = re.sub(r'"RegisterNumber":\W([0-9]+)', r'"RegisterNumber": "\1"', p)
json.loads(sub)

这将匹配所有您有 RegisterNumber 后跟数字的情况。

【讨论】:

    【解决方案3】:

    由于问题是前导零,修复数据的简单方法是将其拆分为行并修复任何出现问题的行。它既便宜又讨厌,但这似乎行得通。

    data = """[
    {
        "name": "Alice",
        "RegisterNumber": 911100020001
    },
    {
        "name": "Bob",
        "RegisterNumber": 000111110300
    }
    ]"""
    result = []
    for line in data.splitlines():
        if ': 0' in line:
            while ": 0" in line:
                line = line.replace(': 0', ': ')
            result.append(line.replace(': ', ': "')+'"')
        else:
            result.append(line)
    data = "".join(result)
    
    arc = json.loads(data)
    print(arc)
    

    【讨论】:

    • 只有在您提前知道数字具有预定义数量的字符时才会这样做。否则,您的数字 0011 可能与 00011 不同。这可能不太可能,因为 0 经常用作填充。但谁知道呢?
    • 我拒绝接受对我在帖子中描述为“廉价和讨厌”的代码的任何批评;-)
    • 哦不,我不是在批评。这里真正的问题是输出无效 json 的 json 序列化程序。
    猜你喜欢
    • 1970-01-01
    • 2023-01-08
    • 1970-01-01
    • 2018-04-12
    • 2016-03-20
    • 1970-01-01
    • 2019-09-11
    • 2022-11-03
    • 2013-03-03
    相关资源
    最近更新 更多