
本文介绍如何高效解析多段结构化文本(如网络设备配置),按逻辑块分割,提取指定键值对(如 host、zone)并组织为字典列表,避免跨块误匹配,适用于日志分析、配置文件处理等场景。
本文介绍如何高效解析多段结构化文本(如网络设备配置),按逻辑块分割,提取指定键值对(如 host、zone)并组织为字典列表,避免跨块误匹配,适用于日志分析、配置文件处理等场景。
在实际运维或自动化脚本开发中,我们常需从类 DSL 的配置文本(如防火墙策略、网络对象定义)中批量提取结构化信息。上述示例文本包含多个以 address-object objectX 开头、以 exit 结尾的逻辑块,但真正需要的是其中缩进行的 host 和 zone 字段——且必须确保每个字典严格对应一个完整块,不能因空行缺失或字段顺序变化而错位。
核心思路是:以“块完成”为触发点,而非依赖固定起始/结束标记。观察可知,每个目标块至少包含全部所需字段(host 和 zone),因此可采用“累积填充 + 达标即提交”的策略:
- 初始化一个空字典列表 answer = [{}],当前字典为 answer[-1];
- 逐行读取,用 str.partition(' ') 安全拆分键值(兼容无空格或多余空格);
- 若键名在目标集合 {'host', 'zone'} 中,存入当前字典;
- 当前字典键数等于目标字段数时,立即追加新空字典 answer.append({}),为下一组准备;
- 最终过滤掉末尾可能残留的空字典。
important_keys = {'host', 'zone'}
with open('config.txt') as infile:
answer = [{}]
for line in infile:
stripped = line.strip()
if not stripped: # 跳过空行,避免干扰状态
continue
key, _, value = stripped.partition(' ')
if key in important_keys:
answer[-1][key] = value.strip('"') # 去除引号,更健壮
# 达成目标字段数量即切换到新字典
if len(answer[-1]) == len(important_keys):
answer.append({})
# 清理末尾空字典
result = [d for d in answer if d]
print(result)
# 输出: [{'host': 'ip1', 'zone': 'zone1'}, {'host': 'ip2', 'zone': 'zone2'}]
⚠️ 注意事项:
- 该方法假设每个块必然包含所有目标字段。若存在缺失(如某块无 zone),需改用显式块界定(例如检测 address-object 行作为块开始,exit 或空行作为结束),再在块内扫描字段;
- partition(' ') 比 split() 更安全,避免因多空格或制表符导致索引错误;
- 实际生产环境建议增加异常处理(如 KeyError 捕获)和字段校验(如 IP 格式验证);
- 若需保留原始字段顺序,可将 important_keys 替换为 OrderedDict 或 Python 3.7+ 的普通 dict(保持插入序)。
此方案简洁、内存友好(流式处理)、逻辑清晰,是解析非标准配置文本的实用范式。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











