zbparse/flask_app/main/json_utils.py

147 lines
5.0 KiB
Python
Raw Normal View History

2024-10-18 18:06:23 +08:00
2024-08-29 16:37:09 +08:00
import json
import re
2024-09-27 18:07:34 +08:00
def extract_content_from_json(string):
2024-10-18 18:06:23 +08:00
"""
输入字符串提取 { } 之间的内容并将其解析为字典
如果使用 insert_missing_commas 修复后仍然失败则尝试返回原始的解析结果如果可能
"""
2024-09-27 18:07:34 +08:00
if not string.strip():
2024-08-29 16:37:09 +08:00
return {}
2024-10-18 18:06:23 +08:00
# 提取第一个匹配的 JSON 对象
2024-09-27 18:07:34 +08:00
match = re.search(r'\{[\s\S]*\}', string)
2024-08-29 16:37:09 +08:00
if match:
2024-10-18 18:06:23 +08:00
json_data = match.group(0)
2024-08-29 16:37:09 +08:00
try:
2024-10-18 18:06:23 +08:00
# 尝试直接解析原始 JSON 数据
return json.loads(json_data)
except json.JSONDecodeError as original_error:
print(f"原始 JSON 解析失败: {original_error}")
try:
# 尝试修复缺失的逗号
fixed_json = insert_missing_commas(json_data)
return json.loads(fixed_json)
except json.JSONDecodeError as fixed_error:
print(f"修复后的 JSON 解析失败: {fixed_error}")
# 可选:返回空字典或其他默认值
return {}
2024-08-29 16:37:09 +08:00
else:
2024-10-18 18:06:23 +08:00
print("json_utils: extract_content_from_json: 未找到有效的 JSON 内容。")
2024-08-29 16:37:09 +08:00
return {}
2024-10-18 18:06:23 +08:00
def insert_missing_commas(json_str):
"""
使用正则表达式在缺失逗号的位置插入逗号
具体来说寻找一个值的结束引号后紧跟着下一个键的开始引号并在中间插入逗号
"""
# 这个正则匹配一个字符串结尾的引号,可能有空白字符,然后是另一个键的引号
pattern = r'(":\s*"[^"]*)"\s*(")'
replacement = r'\1", \2'
previous_str = None
while previous_str != json_str:
previous_str = json_str
json_str = re.sub(pattern, replacement, json_str)
return json_str
2024-08-29 16:37:09 +08:00
def clean_json_string(json_string):
"""清理JSON字符串移除多余的反引号并解析为字典"""
return extract_content_from_json(json_string)
def combine_json_results(json_lists):
"""
将类json格式的列表整合成json数据即大括号{}包裹
"""
combined_result = {}
for json_str in json_lists:
if json_str.strip():
json_data = clean_json_string(json_str)
combined_result.update(json_data)
return combined_result
def nest_json_under_key(data, key):
"""
将给定的字典 data 嵌套在一个新的字典层级下该层级由 key 指定并返回 JSON 格式的字符串
参数:
- data: dict, 要嵌套的原始字典
- key: str, 新层级的键名
返回:
- 嵌套后的 JSON 字符串
"""
# 创建一个新字典,其中包含一个键,该键的值是原始字典
nested_dict = {key: data}
# 将字典转换成 JSON 字符串
nested_json = json.dumps(nested_dict, ensure_ascii=False, indent=4)
return nested_json
def add_keys_to_json(target_dict, source_dict):
"""
source_dict 的内容添加到 target_dict 中的唯一外层键下的字典中
参数:
target_dict (dict): 要更新的目标字典假定只有一个外层键
source_dict (dict): 源字典其内容将被添加到目标字典
返回:
dict: 更新后的字典
"""
if not target_dict:
2024-09-13 15:03:55 +08:00
print("json_utils: Error: Target dictionary is empty.")
2024-08-29 16:37:09 +08:00
return {}
if len(target_dict) != 1:
2024-09-13 15:03:55 +08:00
print("json_utils: Error: Target dictionary must contain exactly one top-level key.")
2024-08-29 16:37:09 +08:00
return target_dict
# 获取唯一的外层键
target_key, existing_dict = next(iter(target_dict.items()))
if not isinstance(existing_dict, dict):
2024-09-13 15:03:55 +08:00
print(f"json_utils: Error: The value under the key '{target_key}' is not a dictionary.")
2024-08-29 16:37:09 +08:00
return target_dict
# 合并字典
existing_dict.update(source_dict)
# 更新原字典
target_dict[target_key] = existing_dict
return target_dict
def rename_outer_key(original_data,new_key):
# 定义新的键名
# new_key = "重新招标, 不再招标和终止招标"
# 提取原始数据中的唯一外层值(假设只有一个外层键)
if not original_data or not isinstance(original_data, dict):
2024-09-13 15:03:55 +08:00
print("json_utils: Error: Invalid input or input is not a dictionary.") # 如果输入无效或不是字典,则返回空字典
return {}
2024-08-29 16:37:09 +08:00
# 使用 next(iter(...)) 提取第一个键的值
original_value = next(iter(original_data.values()), {})
# 创建一个新的字典,使用新的键名
new_data = {new_key: original_value}
2024-10-15 20:57:58 +08:00
return new_data
2024-08-29 16:37:09 +08:00
def transform_json_values(data):
if isinstance(data, dict):
2024-10-16 20:18:55 +08:00
return {key.replace(' ', ''): transform_json_values(value) for key, value in data.items()}
2024-08-29 16:37:09 +08:00
elif isinstance(data, list):
return [transform_json_values(item) for item in data]
elif isinstance(data, bool):
return '' if data else ''
elif isinstance(data, (int, float)):
return str(data)
elif isinstance(data, str):
return data.replace('\n', '<br>')
else:
return data