96 lines
6.4 KiB
Python
96 lines
6.4 KiB
Python
# -*- encoding:utf-8 -*-
|
||
import re
|
||
|
||
def find_keys_by_value(target_value, json_data):
|
||
# 找到值等于目标值或以目标值开头的键
|
||
matched_keys = [k for k, v in json_data.items() if v == target_value]
|
||
if not matched_keys:
|
||
matched_keys = [k for k, v in json_data.items() if isinstance(v, str) and v.startswith(target_value)]
|
||
return matched_keys
|
||
|
||
def find_keys_with_prefix(prefix, json_data):
|
||
# 只提取直接子项,比如 prefix 为 '7.2' 时只提取 '7.2.1', '7.2.2' 但不会提取 '7.3'
|
||
return [k for k in json_data.keys() if k.startswith(prefix) and k[len(prefix):].lstrip('.').isdigit()]
|
||
|
||
def extract_json(data, target_values):
|
||
results = {}
|
||
|
||
# 遍历所有目标值
|
||
for target_value in target_values:
|
||
# 找到所有与目标值匹配的键
|
||
matched_keys = find_keys_by_value(target_value, data)
|
||
|
||
for key in matched_keys:
|
||
# 查找所有以该键为前缀的子键,限制只提取直接子项
|
||
key_and_subheadings = find_keys_with_prefix(key, data)
|
||
|
||
for subkey in key_and_subheadings:
|
||
# 如果子键有多级结构(比如 '7.2.1'),并且是直接子项
|
||
if "." in subkey:
|
||
parent_key = subkey.rsplit('.', 1)[0]
|
||
top_level_key = parent_key.split('.')[0] + '.'
|
||
|
||
# 确保顶级键不会重复添加
|
||
if top_level_key not in results:
|
||
results[top_level_key] = data[top_level_key]
|
||
|
||
# 添加或更新父级键
|
||
if parent_key not in results:
|
||
if parent_key in data:
|
||
results[parent_key] = data[parent_key]
|
||
|
||
# 添加当前子键和它的值
|
||
if subkey in data:
|
||
results[subkey] = data[subkey]
|
||
|
||
return results
|
||
|
||
def extract_json(data, target_values):
|
||
results = {}
|
||
for target_value in target_values:
|
||
matched_keys = find_keys_by_value(target_value, data)
|
||
for key in matched_keys:
|
||
key_and_subheadings = find_keys_with_prefix(key, data)
|
||
for subkey in key_and_subheadings:
|
||
if "." in subkey:
|
||
parent_key = subkey.rsplit('.', 1)[0]
|
||
top_level_key = parent_key.split('.')[0] + '.'
|
||
# 特别处理定标相关的顶级键,确保不会重复添加其他键
|
||
if top_level_key not in results:
|
||
results[top_level_key] = target_value
|
||
# 添加或更新父级键
|
||
if parent_key not in results:
|
||
if parent_key in data:
|
||
results[parent_key] = data[parent_key]
|
||
# 添加当前键
|
||
results[subkey] = data[subkey]
|
||
return results
|
||
|
||
# 测试数据
|
||
data = {
|
||
"7.": "合同授予",
|
||
"7.1": "定标方式",
|
||
"7.1.1": "招标人依据评标委员会推荐的中标候选人确定中标人,国有资金占控股或者主导地位的依法必须进行招标的项目,确定排名第一的中标候选人为中标人。评标委员会推荐中标候选人的数量见投标人须知前附表。",
|
||
"7.1.2": "排名第一的中标候选人放弃中标、因不可抗力不能签订合同、不按照招标文件要求提交履约担保,或者被查实存在影响中标结果的违法行为等情形,不符合中标条件的,招标人可以按照评标委员会提出的中标候选人名单排序依次确定其他中标候选人为中标人,也可以重新招标。",
|
||
"7.1.3": "招标人将自收到评标报告之日起3日内在投标人须知前附表规定的媒介公示中标候选人。公示期不少于3日。投标人或者其他利害关系人对评标结果有异议的,应当在评标结果公示期间提出。招标人自收到异议之日起3日内作出答复;作出答复前,暂停招标投标活动。投标人的异议与答复应当通过“省电子交易平台”在“异议与答复”菜单以书面形式进行,其他利害关系人的异议也应以书面形式向招标人提出。中标候选人公示媒体见投标人须知前附表。",
|
||
"7.1.4": "中标候选人经公示无异议、招标人向交通运输主管部门履行评标结果备案手续后,发出中标通知书。",
|
||
"7.2": "中标通知",
|
||
"7.2.1": "招标人将在本章第3.3款规定的投标有效期内,招标人通过“电子交易平台”以书面形式向中标人发出中标通知书,同时将中标结果通知未中标的投标人。中标通知书发出前,招标人将在投标人须知前附表第7.1.3款规定的媒介发布中标结果公告。",
|
||
"7.2.2": "中标候选人的经营、财务状况发生较大变化或者存在违法行为,招标人认为可能影响其履约能力的,将在发出中标通知书前报请行政监督部门批准后,召集原评标委员会按照招标文件规定的标准和方法审查确认。",
|
||
"7.2.3": "招标人即使已经向中标人发出了中标通知书,若发生下列情况之一者,中标无效。(1)经查实投标人以他人名义投标或以其他方式弄虚作假,骗取中标的;(2)经查实投标人有串通投标的,或向招标人或评标委员会成员以行贿手段谋取中标的;(3)法律、法规规定的其他情形。",
|
||
"7.3": "履约担保",
|
||
"7.3.1": "在签订合同前,中标人应按投标人须知前附表规定的金额、担保形式和招标文件第四章规定的格式向招标人提交履约担保,或事先经过招标人书面认可的履约担保格式向招标人提交履约担保。履约担保金额不得超过中标合同价的10%,详见投标人须知前附表。联合体中标的,其履约担保由牵头人提交,并应符合投标人须知前附表规定的金额、担保形式和招标文件规定的履约担保格式要求。联合体中标的,其履约担保由牵头人递交,并应符合上述要求。",
|
||
"7.3.2": "中标人不能按本章第7.3.1项要求提交履约担保的,视为放弃中标,其投标保证金不予退还,给招标人造成的损失超过投标保证金数额的,中标人还应当对超过部分予以赔偿。",
|
||
}
|
||
|
||
# 提取匹配的目标
|
||
target_values = ["中标"]
|
||
|
||
# 运行提取函数
|
||
extracted_json = extract_json(data, target_values)
|
||
|
||
# 输出结果
|
||
import json
|
||
|
||
print(json.dumps(extracted_json, ensure_ascii=False, indent=4))
|