Python 解析“脏乱差”JSON?这几种实战技巧让你轻松应对不规则数据

简介: 本文详解如何用Python解析现实中的“不规则JSON”:单引号、尾逗号、无引号键、注释、嵌套JSON片段等。推荐`json5`库为主力方案,辅以`ast.literal_eval`、正则提取与容错处理,兼顾安全与实用性。(239字)

在真实世界的数据处理中,我们很少遇到教科书式的标准 JSON。更多时候,面对的是:

  • 单引号代替双引号  
  • 末尾多出逗号  
  • 键名未加引号(如 {name: "Alice"})  
  • 混合了注释(// 这是注释)  
  • 嵌套结构缺失或类型错乱(字符串里藏了 JSON 片段)  
  • 甚至根本不是合法 JSON,而是 JavaScript 对象字面量(JS Object Literal)

这类“不规则 JSON”无法被 Python 内置的 json.loads() 直接解析,强行使用会抛出 JSONDecodeError。但别急——本文将为你提供一套从温和修复到强力解析的完整工具箱,用 Python 轻松驯服这些“野性”数据。


一、场景1:轻微格式错误(单引号、尾逗号等)

典型数据

{
  'name': 'Alice',
  'age': 30,
  'tags': ['a', 'b',],
}

✅ 解法:使用 ast.literal_eval(仅限 Python 字面量)

如果数据本质是 Python 字典/列表字面量(而非严格 JSON),可尝试:

import ast
dirty_str = "{'name': 'Alice', 'age': 30, 'tags': ['a', 'b',]}"
try:
    data = ast.literal_eval(dirty_str)
    print(data)  # {'name': 'Alice', 'age': 30, 'tags': ['a', 'b']}
except (ValueError, SyntaxError) as e:
    print("无法解析为 Python 字面量")

⚠️ 注意:ast.literal_eval 只支持 str, bytes, int, float, list, dict, tuple, bool, None,不支持 NaNInfinity 等。


二、场景2:含注释、尾逗号、键无引号(类 JS 对象)

典型数据

{
  // 用户信息
  name: "Bob",
  age: 25,
  hobbies: [
    "coding",
    "gaming",  // 末尾逗号
  ],
}

✅ 解法:使用 json5 库(推荐!)

JSON5 是 JSON 的扩展,支持注释、单引号、尾逗号、无引号键等,完美兼容 JavaScript 风格对象。

安装:

pip install json5

使用:

import json5
with open('config.js', 'r', encoding='utf-8') as f:
    data = json5.load(f)  # 或 json5.loads(string)
print(data['name'])  # Bob

✅ 优点:安全、标准、广泛用于前端配置文件(如 .babelrc, tsconfig.json 变体)。


三、场景3:字符串中嵌套未转义的 JSON 片段

典型数据

{
  "log": "User {\"id\": 123, \"action\": \"login\"} performed"
}

你可能想提取内部的 {"id": 123, ...},但它被包裹在字符串中。

✅ 解法:正则 + 递归解析

import json
import re
def extract_and_parse_nested_json(text):
    # 匹配最外层的 {...},但需确保是完整 JSON 对象
    pattern = r'\{(?:[^{}]|(?R))*\}'  # 递归正则(Python 不支持 (?R),改用循环)
    
    # 更稳健的做法:逐字符扫描括号匹配
    def find_outer_braces(s):
        stack = 0
        start = -1
        for i, c in enumerate(s):
            if c == '{':
                if stack == 0:
                    start = i
                stack += 1
            elif c == '}':
                stack -= 1
                if stack == 0 and start != -1:
                    return s[start:i+1]
        return None
    nested = find_outer_braces(text)
    if nested:
        try:
            return json.loads(nested)
        except json.JSONDecodeError:
            return None
    return None
log_str = 'User {"id": 123, "action": "login"} performed'
inner = extract_and_parse_nested_json(log_str)
print(inner)  # {'id': 123, 'action': 'login'}

四、场景4:完全非结构化,但有规律可循

比如日志文件中的混合内容:

INFO: {user: "Tom", status: ok}
ERROR: Failed to parse {data: [1,2,,3]}

✅ 解法:先用正则提取疑似 JSON 片段,再用容错解析器

结合 json5 + 异常捕获:

import json5
import re
log_line = 'ERROR: Failed to parse {data: [1,2,,3]}'
# 提取花括号包围的内容
match = re.search(r'\{.*\}', log_line)
if match:
    candidate = match.group()
    try:
        data = json5.loads(candidate)
        print("Parsed:", data)
    except Exception as e:
        print("Still invalid:", e)

💡 提示:对于 [, ,] 这类空元素,json5 也支持(视为 null)。


五、终极武器:自定义解析器 or LLM 辅助(慎用)

若数据极度混乱(如混合 HTML、自定义 DSL),可考虑:

  • 使用 larkply 构建自定义语法解析器;
  • 用大模型(如本地 LLM)将“脏数据”重写为合法 JSON(适合低频、高价值场景)。

但绝大多数情况,json5 + 正则清洗 + 异常处理 已足够覆盖。


最佳实践建议

  1. 优先用 json5:它能解决 90% 的“类 JSON”问题;
  2. 不要用 eval():极其危险,可能执行任意代码;
  3. 记录解析失败样本:用于后续规则优化;
  4. 在数据入口做标准化:若可控,推动上游输出合法 JSON。

结语

不规则 JSON 不是“错误”,而是现实世界的常态。Python 生态提供了从轻量级(ast)到工业级(json5)的多种工具,关键在于识别数据“脏”在哪一层,然后选择匹配的清洗策略。

记住:解析不是目的,可靠地获取结构化信息才是。用对工具,那些看似混乱的字符串,终将成为你数据管道中的清晰字段。

目录
相关文章
|
1月前
|
人工智能 自然语言处理 数据可视化
作为一名在读博士生,我在日常是如何与 AI 协作的
本文是一位AI方向博士生的AI协作实践手记:主张“当同事,不当工具”,提出元提示词、苏格拉底追问、多模型协同与经验沉淀四大方法论,覆盖划词问答、文献研读、科研绘图、代码开发等全科研场景,强调人机共生、流程提效与持续进化。
|
人工智能 移动开发 自然语言处理
阿里云百炼产品月刊【2025年9月】
本月通义千问模型大升级,新增多模态、语音、视频生成等高性能模型,支持图文理解、端到端视频生成。官网改版上线全新体验中心,推出高代码应用与智能体多模态知识融合,RAG能力增强,助力企业高效部署AI应用。
1786 0
|
3月前
|
Linux 开发者 iOS开发
IntelliJ IDEA 的「闪电操作」:这些 Quick 技巧让你编码快如疾风
本文详解 IntelliJ IDEA 六大高效“Quick”技巧:Quick Fix(Alt+Enter)、Quick Doc(Ctrl+Q)、Quick Evaluate(Alt+F8)、Quick Switch Scheme(Ctrl+`)、Quick Definition(Ctrl+Shift+I)及 Live Templates。助你减少鼠标操作,提升编码流畅度与思维连贯性。(239字)
371 9
|
1月前
|
人工智能 安全 前端开发
Team 版 OpenClaw:HiClaw 开源,5 分钟完成本地安装
HiClaw 基于 OpenClaw、Higress AI Gateway、Element IM 客户端+Tuwunel IM 服务器(均基于 Matrix 实时通信协议)、MinIO 共享文件系统打造。
9945 34
|
3月前
|
人工智能 自然语言处理 安全
Claude Code 插件登陆 VS Code:开发者迎来 AI 编程新利器
Anthropic正式发布Claude Code——VS Code官方插件,支持多语言智能补全、代码解释、错误诊断与安全重构。隐私优先、长上下文(200K tokens)处理能力强,显著优于Copilot的可解释性与代码质量,已获开发者广泛好评。(239字)
7412 5
|
2月前
|
人工智能 安全 JavaScript
Claude Code 中的 Commands、Skills 与 Agents:不是进阶路径,而是协作维度
本文澄清Claude Code中Commands、Skills、Agents并非线性进阶关系,而是面向不同协作粒度的互补机制:Commands用于即时原子操作,Skills封装可复用专业能力,Agents承担目标导向的自主任务。三者构成“协作三角”,应依任务复杂度灵活选用或组合,核心是扩展而非替代人类能力。(239字)
2148 8
|
4月前
|
Java Windows
IDEA 插件 SpotBugs Idea 1.2.7.zip 使用详解(一步步教你排查Bug)
SpotBugs Idea 1.2.7.zip 是IntelliJ IDEA的Java静态分析插件,可检测空指针、资源泄漏等潜在问题。下载后通过Settings→Plugins→Install from Disk安装,重启IDEA即可使用。分析项目时右键选择“Analyze with SpotBugs”,结果按严重程度分级显示,支持跳转定位代码。兼容性佳,误报可忽略或注解屏蔽。
750 144
|
1月前
|
大数据 数据库 数据库管理
EmEditor安装教程 Windows版:详细步骤+激活密钥输入+桌面快捷方式创建指南
EmEditor是功能强大的Windows文本编辑器,支持宏、Unicode及大数据/CSV处理,适用于网页设计、编程、出版、数据库与服务器管理等场景。本文详述其安装、激活(含终身密钥)及快捷方式创建方法。
|
人工智能 安全 API
大模型推理主战场:通信协议的标配
DeepSeek加速了模型平权,大模型推理需求激增,性能提升主战场从训练转向推理。SSE(Server-Sent Events)和WebSocket成为大模型应用的标配网络通信协议。SSE适合服务器单向推送实时数据,如一问一答场景;WebSocket支持双向实时通信,适用于在线游戏、多人协作等高实时性场景。两者相比传统HTTPS协议,能更好地支持流式输出、长时任务处理和多轮交互,满足大模型应用的需求。随着用户体量扩大,网关层面临软件变更、带宽成本及恶意攻击等挑战,需通过无损上下线、客户端重连机制、压缩算法及安全防护措施应对。
1864 176
大模型推理主战场:通信协议的标配
|
4月前
|
SQL 存储 分布式计算
九、HQL DQL七大查询子句
Hive 查询写得清楚,数据分析就能更顺手。我们这次从入门角度出发,带你理清 Hive 中最常用的七个查询子句(FROM、WHERE、GROUP BY、HAVING、SELECT、ORDER BY、LIMIT),结合执行顺序梳理每一步的用法与注意事项。每个子句都有配套案例,还有实战练习题帮你快速上手。如果你刚开始学习 Hive 查询,或希望把基础打得更扎实,这篇内容值得收藏。
231 9