如何在Python中解析混有普通文本的JSON数据?
从混合文本与JSON的大型报告中提取并解析JSON对象
解决方案思路
核心是准确定位并提取完整的JSON对象——JSON对象始终以{开头、}结尾,且嵌套结构的括号成对匹配。通过跟踪括号的嵌套层级,自动捕获每个完整的JSON块,再逐一解析提取目标值即可。
实现代码
以下是内存友好的处理方案(适合大型文件,无需一次性加载全部内容):
import json def extract_and_parse_json(file_path, target_fields): extracted_results = [] current_json_chars = [] bracket_depth = 0 with open(file_path, 'r', encoding='utf-8') as file: # 逐行处理,避免一次性加载大文件到内存 for line in file: # 逐字符遍历,精准跟踪括号层级 for char in line: if char == '{': bracket_depth += 1 current_json_chars.append(char) elif char == '}': bracket_depth -= 1 current_json_chars.append(char) # 括号层级回到0,说明捕获到一个完整的JSON对象 if bracket_depth == 0: json_str = ''.join(current_json_chars).strip() try: # 解析JSON字符串为Python字典 json_obj = json.loads(json_str) # 提取指定字段,支持嵌套层级(用点分隔) target_values = {} for field in target_fields: nested_parts = field.split('.') temp = json_obj for part in nested_parts: temp = temp.get(part) if temp is None: break target_values[field] = temp extracted_results.append(target_values) except json.JSONDecodeError: # 跳过无效的JSON片段 print(f"跳过无效JSON: {json_str[:60]}...") # 重置当前JSON缓存 current_json_chars = [] elif bracket_depth > 0: # 仅记录处于JSON对象内部的字符 current_json_chars.append(char) return extracted_results # 使用示例 report_path = "你的报告文件路径.txt" # 定义需要提取的字段,嵌套字段用点分隔(如text1.text2.text3) target_fields = ["text8", "text1.text2.text3"] results = extract_and_parse_json(report_path, target_fields) # 输出结果 for index, values in enumerate(results, start=1): print(f"第{index}个JSON对象的目标值:") for field, value in values.items(): print(f" {field}: {value}")
代码说明
- 括号层级跟踪:通过
bracket_depth变量记录当前所处的JSON嵌套层级,只有当层级从0变为1时开始记录字符,层级回到0时完成一个JSON对象的捕获。 - 内存友好处理:逐行、逐字符遍历文件,不会一次性加载整个大文件到内存,适合处理超大报告。
- 目标字段提取:支持嵌套字段的提取(如
text1.text2.text3对应JSON中的text1->text2->text3),并自动处理字段不存在的情况。 - 错误处理:捕获JSON解析失败的情况,跳过无效的JSON片段,避免程序崩溃。
为什么之前的方法无效
json.loads():要求传入完整且标准的JSON字符串,你直接传入包含大量非JSON内容的混合文本,自然解析失败。json.dumps():作用是将Python对象转换为JSON字符串,你把整个文本转成JSON字符串后,所有内容都变成了一个字符串值,根本无法解析其中的JSON结构。
注意事项
- 如果报告中存在非JSON的
{}片段(比如普通文本中的括号),代码会尝试解析但捕获错误后跳过,不影响有效JSON的提取。 - 确保报告中的JSON是标准格式(键和字符串均使用双引号),如果存在单引号格式的JSON,需要先添加预处理步骤(如替换单引号为双引号,注意区分字符串内部的单引号)。
内容的提问来源于stack exchange,提问作者Helbirah
相关产品推荐
相关产品推荐

