查看: 99|回复: 1

Python解析非标准JSON:5种场景与json5/ast.literal_eval方案对比

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
在日常开发中,从日志、配置或第三方接口拿到的JSON数据往往不符合标准规范。Python自带的json.loads()遇到单引号、末尾逗号、无引号键名或注释会直接抛出异常。本文整理5种常见非标准场景,并提供从ast.literal_eval到json5的完整解决方案,帮你快速清洗数据。

场景一:单引号+末尾逗号
手写配置或API日志中经常出现这种格式:
  1. data = "{'name': 'Tom', 'age': 18,}"
复制代码

方案1:ast.literal_eval(推荐轻量场景)
  1. import ast
  2. result = ast.literal_eval(data)
  3. # {'name': 'Tom', 'age': 18}
复制代码
ast.literal_eval能安全解析Python字面量,包括单引号、末尾逗号、True/False/None。但它不能解析真正的JSON扩展(如null、true)。

方案2:正则替换+json.loads
  1. import json, re
  2. def fix_json(s):
  3.     s = re.sub(r"(?<!\\)'", '"', s)
  4.     s = re.sub(r',\s*([\]\}])', r'\1', s)
  5.     return json.loads(s)
  6. result = fix_json(data)
复制代码
这种方法灵活但正则容易漏掉字符串内部的引号,复杂场景建议慎用。

场景二:键名未加引号
  1. data = '{name: "Tom", age: 18}'
复制代码
方案:使用demjson3或json5
  1. pip install demjson3
  2. import demjson3
  3. result = demjson3.decode(data)
复制代码
或使用更标准的json5:
  1. pip install json5
  2. import json5
  3. result = json5.loads(data)
复制代码
json5是JSON5格式的Python实现,支持无引号键名、单引号、注释、尾随逗号等所有非标准特性,且维护活跃。

场景三:包含注释的JSON
某些配置文件会夹杂//或/* */注释:
  1. {
  2.     "name": "Tom", // 用户名
  3.     "age": 18
  4. }
复制代码
方案1:正则清除注释
  1. import re
  2. def strip_comments(s):
  3.     s = re.sub(r'//.*', '', s)
  4.     s = re.sub(r'/\*.*?\*/', '', s, flags=re.DOTALL)
  5.     return s
复制代码
清除后再用json.loads解析。
方案2:直接用json5一步到位
  1. import json5
  2. with open('config.json5', 'r') as f:
  3.     data = json5.load(f)
复制代码

场景四:JavaScript风格的特殊值
数据中包含undefined、NaN、Infinity:
  1. {"value": undefined, "num": NaN}
复制代码
方案:demjson3能自动转换(undefined→None,NaN→nan,Infinity→inf)。json5同样支持。

场景五:十六进制数字(如0xFF)
标准JSON不支持,但json5可以解析。

方案对比
- json.loads:仅标准JSON,快但严格。
- ast.literal_eval:Python字面量,安全无依赖,不能识别null/true/false。
- demjson3:功能较全,但社区维护少,新版Python可能不兼容。
- json5:语法标准、功能全面、持续维护,推荐作为主力方案。
- 正则替换:适合简单一次性清洗,容易出错。

实践建议
1. 如果数据来源固定且简单(如手写配置),优先用ast.literal_eval。
2. 数据格式未知且复杂,直接上json5,开箱即用。
3. 生产环境对性能敏感:先用json5清洗并保存为标准JSON,后续用json.loads。
4. 永远不要信任外部JSON,尽量要求对方输出规范格式。

总结
非标准JSON的本质是生产方与消费方对格式定义不一致。Python生态提供了从轻量ast.literal_eval到全面json5的多种方案,选哪个取决于数据有多“脏”。json5是目前最推荐的折中选择——既有广泛的标准支持,又能覆盖绝大多数异常情况。
回复

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Python解析非标准JSON:5种场景与json5/ast.literal_eval方案对比

感谢分享,这篇文章非常实用!我平时也经常遇到手写配置里单引号加末尾逗号的情况,之前一直用正则硬改,确实容易翻车。你提到的ast.literal_eval和json5的对比很清楚,尤其是性能敏感时先清洗再存标准JSON的思路很实在。以后遇到带注释的配置文件,直接上json5省心多了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-6-15 11:10 , Processed in 0.024833 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部