Python解析非标准JSON的踩坑记录和解决方案

 更新时间:2026年06月15日 08:14:22   作者:detayun  
JSON是Web开发中最常用的数据交换格式,本文整理了几种常见的非标准JSON场景,以及对应的解决方案,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下

前言

JSON是Web开发中最常用的数据交换格式,但现实世界从来不按规范来。你可能遇到过这些情况:

  • 单引号代替双引号:{'name': 'Tom'}
  • 末尾多了逗号:{"name": "Tom",}
  • 键名没加引号:{name: "Tom"}
  • 注释混在里面:{"name": "Tom" // this is a comment}

Python自带的json.loads()遇到这些会直接报错。本文整理了几种常见的非标准JSON场景,以及对应的解决方案。

场景一:单引号 + 末尾逗号

这是最常见的"脏数据",通常来自手写配置或某些API的日志。

import json

data = "{'name': 'Tom', 'age': 18,}"  # 单引号 + 末尾逗号
# json.loads(data)  # 报错:JSONDecodeError

解决方案1:用ast.literal_eval(推荐)

import ast

data = "{'name': 'Tom', 'age': 18,}"
result = ast.literal_eval(data)
print(result)  # {'name': 'Tom', 'age': 18}

ast.literal_eval可以安全地解析Python字面量,包括单引号字符串、末尾逗号、True/False/None等。

注意:它只能解析Python语法能识别的值,不能处理真正的JSON扩展。

解决方案2:先替换再解析

import json
import re

def fix_json(s):
    # 单引号 → 双引号(注意避免替换字符串内部的引号)
    s = re.sub(r"(?<!\\)'", '"', s)
    # 去除末尾逗号
    s = re.sub(r',\s*([\]}])', r'\1', s)
    return json.loads(s)

data = "{'name': 'Tom', 'age': 18,}"
result = fix_json(data)
print(result)

这种方式更灵活,但正则替换有边界风险,复杂场景容易漏。

场景二:键名未加引号

data = '{name: "Tom", age: 18}'  # 键名没引号,不是合法JSON

解决方案:用demjson3库

pip install demjson3
import demjson3

data = '{name: "Tom", age: 18}'
result = demjson3.decode(data)
print(result)  # {'name': 'Tom', 'age': 18}

demjson3是目前处理非标准JSON最强的第三方库,支持:

  • 无引号键名
  • 单引号
  • 末尾逗号
  • 注释(///* */
  • JavaScript风格的undefinedNaNInfinity

场景三:包含注释的JSON

某些配置文件会在JSON里加注释,这在标准JSON中是不允许的。

{
  "name": "Tom",  // 用户名
  "age": 18       /* 成年了 */
}

解决方案:先清注释,再解析

import json
import re

def strip_comments(s):
    # 去除 // 注释
    s = re.sub(r'//.*', '', s)
    # 去除 /* */ 注释
    s = re.sub(r'/\*.*?\*/', '', s, flags=re.DOTALL)
    return s

raw = '''
{
  "name": "Tom",  // 用户名
  "age": 18
}
'''
clean = strip_comments(raw)
result = json.loads(clean)
print(result)

或者直接用demjson3一步到位:

import demjson3
result = demjson3.decode(raw)

场景四:JavaScript风格的特殊值

{
  "value": undefined,
  "number": NaN,
  "big": Infinity
}

这些在标准JSON中不存在,但在JS生态中很常见。

JS值JSON等价demjson3处理结果
undefinedNone
NaNnan(float)
Infinityinf(float)
true/falsetrue/false正常解析
import demjson3
data = '{value: undefined, num: NaN, big: Infinity}'
result = demjson3.decode(data)
print(result)
# {'value': None, 'num': nan, 'big': inf}

方案对比

方案适用场景优点缺点
json.loads标准JSON快、安全、内置只能处理标准JSON
ast.literal_evalPython风格字典安全、内置不识别null/true/false
demjson3几乎所有非标准情况功能最全性能较慢,依赖第三方
正则替换+json简单单引号/逗号场景轻量容易出错,维护成本高

实践建议

  1. 能用标准JSON就用标准JSON——这是根治问题的方式
  2. 数据来源可信 + 格式简单 → 用ast.literal_eval,性能好且安全
  3. 数据来源杂、格式乱 → 直接上demjson3,别自己造轮子
  4. 生产环境对性能敏感 → 先做数据清洗,再用json.loads

知识扩展

在 Python 中解析非标准 JSON 数据,常见的情况包括:

  • 键名没有引号({name: "value"}
  • 字符串使用单引号({'key': 'value'}
  • 存在注释(// comment 或 /* comment */
  • 尾随逗号([1, 2, 3,]
  • 十六进制数字(0xFF

处理这类数据不能直接用标准库 json,需要借助第三方库或手动预处理。

1.推荐方案:使用 json5 库(最标准、最全面)

json5 是 JSON5 格式的官方 Python 实现,JSON5 是 JSON 的超集,支持上述所有非标准特性。

pip install json5
import json5
data_str = """
{
  // 这是注释
  name: 'Alice',   // 键名无引号,字符串单引号
  age: 30,
  tags: ['dev', 'test',],  // 尾随逗号
}
"""
obj = json5.loads(data_str)
print(obj)  # {'name': 'Alice', 'age': 30, 'tags': ['dev', 'test']}

也可以从文件读取:

with open('data.json5', 'r', encoding='utf-8') as f:
    obj = json5.load(f)

2.备选方案:demjson(老牌,但维护较少)

demjson 也能处理许多非标准情况,但更新不活跃,且依赖较多。

pip install demjson
import demjson
data = "{name: 'Bob', age: 25,}"
obj = demjson.decode(data)
print(obj)

3.手动预处理(适合简单情况)

如果只有单引号问题,可以用正则或字符串替换:

import json
data = "{'name': 'John', 'age': 30}"   # 单引号
# 简单替换:将外层的单引号替换为双引号
# 注意:仅适用于字符串值不包含引号的情况,否则有风险
data_clean = data.replace("'", '"')
obj = json.loads(data_clean)
print(obj)

缺点:若字符串内容本身就含有单引号或双引号,会破坏结构。

4.使用 ast.literal_eval()(仅限 Python 字面量)

如果数据格式严格符合 Python 字面量(单引号、无键名引号等),可以用 ast.literal_eval,但不能解析 truefalsenull(Python 是 TrueFalseNone)。

import ast
data = "{name: 'Alice', age: 30}"
obj = ast.literal_eval(data)   # 返回 dict
print(obj)  # {'name': 'Alice', 'age': 30}

局限性:布尔值和 null 会报错,需要手动替换。

总结推荐

  • 首选 json5:功能最全、语法标准、维护良好。
  • 简单单引号替换:仅适合临时一次性脚本,且数据格式可控。
  • 避免使用 demjson:长期未更新,可能不兼容新版 Python。

下面是使用 json5 的完整示例:

import json5
# 示例非标准 JSON
non_standard = """
{
  // 这是一条注释
  "name": "Mike",
  "age": 28,
  "address": {
    city: 'New York',
    zip: 10001,
  },
}
"""
parsed = json5.loads(non_standard)
print(parsed['address']['city'])  # New York

如果你需要处理大量类似数据,建议先统一转换成标准 JSON 格式保存,再使用原生 json 解析提高性能。

总结

非标准JSON的本质是:数据生产方和消费方对"什么是合法JSON"的定义不一致

Python生态的解决思路也很清晰:

  • 轻量场景 → ast.literal_eval
  • 重度场景 → demjson3
  • 极致场景 → 自己写清洗逻辑

选哪个,取决于你的数据有多"脏"。

到此这篇关于Python解析非标准JSON的踩坑记录和解决方案的文章就介绍到这了,更多相关Python解析非标准JSON内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一文掌握Python GUI开发利器PySide2的实战指南

    一文掌握Python GUI开发利器PySide2的实战指南

    PySide2 是由 Qt 公司官方推出的 Python 绑定库,为开发跨平台,现代化 GUI 提供了强大而灵活的支持,下面就跟随小编一起来了解下PySide2的具体使用吧
    2025-07-07
  • 用Python实现BP神经网络(附代码)

    用Python实现BP神经网络(附代码)

    这篇文章主要介绍了用Python实现BP神经网络(附代码),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • Pytorch各种维度变换函数总结

    Pytorch各种维度变换函数总结

    本文对于PyTorch中的各种维度变换的函数进行总结,包括reshape()、view()、resize_()、transpose()、permute()、squeeze()、unsqeeze()、expand()、repeat()函数的介绍和对比,感兴趣的可以了解一下
    2024-02-02
  • 如何用python复制粘贴excel指定单元格(可保留格式)

    如何用python复制粘贴excel指定单元格(可保留格式)

    这篇文章主要给大家介绍了关于如何用python复制粘贴excel指定单元格(可保留格式)的相关资料,利用python操作excel非常方便,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-07-07
  • Python自动化部署工具Fabric的简单上手指南

    Python自动化部署工具Fabric的简单上手指南

    这篇文章主要介绍了Python自动化部署工具Fabric的简单上手指南,涵盖Fabric的安装、fabric的远程操作与维护等方面,需要的朋友可以参考下
    2016-04-04
  • python GUI库图形界面开发之PyQt5拖放控件实例详解

    python GUI库图形界面开发之PyQt5拖放控件实例详解

    这篇文章主要介绍了python GUI库图形界面开发之PyQt5使用拖放控件实例详解,需要的朋友可以参考下
    2020-02-02
  • Python处理大量Excel文件的十个技巧分享

    Python处理大量Excel文件的十个技巧分享

    每天被大量Excel文件折磨的你看过来!这是一份Python程序员整理的实用技巧,不说废话,直接上干货,文章通过代码示例讲解的非常详细,需要的朋友可以参考下
    2025-05-05
  • Python实现消消乐小游戏

    Python实现消消乐小游戏

    本文主要介绍了Python实现消消乐小游戏,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • python虚拟环境virtualenv的安装与使用

    python虚拟环境virtualenv的安装与使用

    virtualenv用于创建独立的Python环境,多个Python相互独立,互不影响,它能够:1. 在没有权限的情况下安装新套件 2. 不同应用可以使用不同的套件版本 3. 套件升级不影响其他应用
    2017-09-09
  • python自动化实现的简单使用

    python自动化实现的简单使用

    本文主要介绍了python自动化实现的简单使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06

最新评论