JSON原始数据
JSON文件中的数据(带有//单行注释)
{
"BigIntSupported": 995815895020119788889,
"date": "20180322",
"message": "Success !",
"status": 200,
"city": "北京",
"count": 632,
"data": {
"shidu": "34%",
"pm25": 73,
"pm10": 91,
"quality": "良",
"wendu": "5",
"ganmao": "极少数敏感人群应减少户外活动",
"yesterday": {
"date": "21日星期三",
"sunrise": "06:19",
"high": "高温 11.0℃", // 最高温
"low": "低温 1.0℃",// 最低温
"sunset": "18:26",//
"aqi": 85,
"fx": "南风",
"fl": "<3级",
"type": "多云",
"notice": "阴晴之间,谨防紫外线侵扰"
},
"forecast": [
{
"date": "22日星期四",
"sunrise": "06:17",
"high": "高温 17.0℃", // 最高温
"low": "低温 1.0℃",// 最低温
"sunset": "18:27",
"aqi": 98,
"fx": "西南风",
"fl": "<3级",
"type": "晴",
"notice": "愿你拥有比阳光明媚的心情"
},
{
"date": "23日星期五",
"sunrise": "06:16",
"high": "高温 18.0℃", // 最高温
"low": "低温 5.0℃",// 最低温
"sunset": "18:28",
"aqi": 118,
"fx": "无持续风向",
"fl": "<3级",
"type": "多云",
"notice": "阴晴之间,谨防紫外线侵扰"
},
{
"date": "24日星期六",
"sunrise": "06:14",
"high": "高温 21.0℃", // 最高温
"low": "低温 7.0℃",// 最低温
"sunset": "18:29",
"aqi": 52,
"fx": "西南风",
"fl": "<3级",
"type": "晴",
"notice": "愿你拥有比阳光明媚的心情"
},
{
"date": "25日星期日",
"sunrise": "06:13",
"high": "高温 22.0℃",
// 最高温
"low": "低温 7.0℃",
// 最低温
"sunset": "18:30",
"aqi": 71,
"fx": "西南风",
"fl": "<3级",
"type": "晴",
// json 数据中字符串中都带有 双斜杠 和 换行符
"notice": "愿你--拥有//\n\r比阳光明媚的心情"
},
{
"date": "26日星期一",
"sunrise": "06:11",
// json 数据中字符串带有 双斜杠
"high": "//高温 21.0℃", // 最高温
"low": "低温 8.0℃",// 最低温
"sunset": "18:31",
"aqi": 97,
"fx": "西南风",
"fl": "<3级",
"type": "多云",
"notice": "阴晴之间,谨防紫外线侵扰"
}
]
}
}
解决思路
方式一:正则表达式提取过滤
正则表达式-知识及教程
推荐使用:菜鸟教程-正则表达式-教程
Python3 正则表达式 re 模块:菜鸟教程-Python3 正则表达式
可以可视化显示【正则表达式】提取到的内容
Python 实现
提取单行注释的正则表达式:
(?<!\\)//(?=(?:[^"]*"[^"]*")*[^"]*$).*?(?=\n|$)
代码实现:
# json 包
import json
# 正则表达式的包
import re
# 加载带有注释的json
def load_json_with_comments(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# 使用正则表达式移除中文注释
clean_data = re.sub(r'(?<!\\)//(?=(?:[^"]*"[^"]*")*[^"]*$).*?(?=\n|$)', '', content, flags=re.S)
return json.loads(clean_data)
# 使用预处理的方法加载包含注释的 JSON 数据
data = load_json_with_comments('./File/xxxx.json')
print(data)
方式二:按字符串划分内容过滤
Python 实现
单行注释的特征:
结构: 以 双斜杠 开头 换行符 结尾 及 中间注释内容部分
json数据的特征:
结构:字段名 及 字符串 都是以 " " 双引号 包裹
难点:如果字符串中也有这样的内容,仅仅考虑双斜杠这个特征 将无法区分是【注释内容】还是【字符串内容】
处理逻辑:
*核心:完整保留 双引号 内的,处理双引号外的 注释内容(双引号内的为字符部分,双引号外的为非字符部分)
- 使用 " 双引号 进行 内容分割(内容被分成:非字符,字符,非字符,字符…)
- 对【字符】和【非字符】部分需要分开处理(加逻辑判断)
- 【字符部分】需要 补回 分割时去掉的双引号
- 【非字符部分】需要 对 注释部分 进行 剔除
代码实现:
# json 包
import json
# 加载带有注释的json
def load_json_with_comments(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# 用 " 分割 JSON 数据中的字符串和非字符串部分
parts = content.split('"')
cleaned_parts = []
# 第一段为 非字符串部分(首次进入则进入非字符串部分处理)
in_string = False
# 逐个处理字符串和非字符串部分
for part in parts:
if in_string:
# 字符串部分, 保留原样, 重新把 双引号 加回去
cleaned_parts.append(f'"{part}"')
else:
# 非字符串部分,移除可能的注释
# 注释是单行注释,单行注释 开头 双斜杠 结尾 换行符
lines = part.split('\n')
cleaned_lines = []
for line in lines:
# 非注释内容 与 注释内容 区别在开头的双斜杠
# 截取 双斜杠 前的内容进行保留
# split 未找到 分割内容 会保留 完整字符 到l ist集合
line = line.split('//')[0]
cleaned_lines.append(line)
# 最后 用 换行符 连接起来, 补上 被分割的换行符
cleaned_part = '\n'.join(cleaned_lines).strip()
# 判断 非字符部分最后拼接 是否有值
if cleaned_part:
cleaned_parts.append(cleaned_part)
# 切换 字符串/非字符 状态
in_string = not in_string
# 最终将清除注释内容的各个部分拼接回去
cleaned_content = ''.join(cleaned_parts)
# 解析处理后的 JSON 数据
return json.loads(cleaned_content)
# 使用预处理的方法加载包含注释的 JSON 数据
data = load_json_with_comments('./File/xxxx.json')
print(data)