如何改进Python正则表达式提取Cisco配置中的Cloudflare网络对象组
Cisco配置中提取Cloudflare网络对象组的正则优化方案
问题背景
需要用Python和正则表达式从Cisco配置里提取以object-group network Cloudflare开头的网络对象组,后续包含一条或多条 network-object 子网 掩码格式的条目。现有正则表达式(?P<name>object-group network Cloudflare)\n(?P<subnets> network-object \d+\.\d+\.\d+\.\d+ \d+\.\d+\.\d+\.\d+\n)*仅能匹配到对象组头部,子网分组无法正确捕获所有条目,需要优化。
配置示例:
object-group network Cloudflare network-object 173.245.48.0 255.255.240.0 network-object 103.21.244.0 255.255.252.0 network-object 103.22.200.0 255.255.252.0 network-object 103.31.4.0 255.255.252.0 network-object 141.101.64.0 255.255.192.0 network-object 108.162.192.0 255.255.192.0 network-object 190.93.240.0 255.255.240.0 network-object 188.114.96.0 255.255.240.0 network-object 197.234.240.0 255.255.252.0 network-object 198.41.128.0 255.255.128.0 network-object 162.158.0.0 255.254.0.0 network-object 104.16.0.0 255.248.0.0 network-object 104.24.0.0 255.252.0.0 network-object 172.64.0.0 255.248.0.0 network-object 131.0.72.0 255.255.252.0
原正则问题分析
原正则中subnets分组使用*重复匹配,但重复捕获组只会保留最后一次匹配的结果,导致无法获取所有子网条目。
优化方案
方案1:捕获所有子网到单个分组后拆分
通过非捕获组匹配所有子网行,将全部子网内容捕获到一个分组中,再在Python中拆分处理:
正则表达式:
^object-group network Cloudflare\n(?P<subnets>( network-object \d+\.\d+\.\d+\.\d+ \d+\.\d+\.\d+\.\d+\n?)+)
Python代码示例:
import re config = """object-group network Cloudflare network-object 173.245.48.0 255.255.240.0 network-object 103.21.244.0 255.255.252.0 network-object 103.22.200.0 255.255.252.0 network-object 103.31.4.0 255.255.252.0 network-object 141.101.64.0 255.255.192.0 network-object 108.162.192.0 255.255.192.0 network-object 190.93.240.0 255.255.240.0 network-object 188.114.96.0 255.255.240.0 network-object 197.234.240.0 255.255.252.0 network-object 198.41.128.0 255.255.128.0 network-object 162.158.0.0 255.254.0.0 network-object 104.16.0.0 255.248.0.0 network-object 104.24.0.0 255.252.0.0 network-object 172.64.0.0 255.248.0.0 network-object 131.0.72.0 255.255.252.0""" pattern = re.compile(r'^object-group network Cloudflare\n(?P<subnets>( network-object \d+\.\d+\.\d+\.\d+ \d+\.\d+\.\d+\.\d+\n?)+)', re.MULTILINE) match = pattern.search(config) if match: subnets_raw = match.group('subnets') subnet_list = [line.strip() for line in subnets_raw.split('\n') if line.strip()] print("提取的子网条目:") for subnet in subnet_list: print(subnet)
方案2:先定位对象组再提取子网
先匹配Cloudflare对象组的整体内容范围,再用findall单独提取所有子网及掩码:
Python代码示例:
import re config = """object-group network Cloudflare network-object 173.245.48.0 255.255.240.0 network-object 103.21.244.0 255.255.252.0 network-object 103.22.200.0 255.255.252.0 network-object 103.31.4.0 255.255.252.0 network-object 141.101.64.0 255.255.192.0 network-object 108.162.192.0 255.255.192.0 network-object 190.93.240.0 255.255.240.0 network-object 188.114.96.0 255.255.240.0 network-object 197.234.240.0 255.255.252.0 network-object 198.41.128.0 255.255.128.0 network-object 162.158.0.0 255.254.0.0 network-object 104.16.0.0 255.248.0.0 network-object 104.24.0.0 255.252.0.0 network-object 172.64.0.0 255.248.0.0 network-object 131.0.72.0 255.255.252.0""" # 匹配对象组整体内容 group_pattern = re.compile(r'^object-group network Cloudflare\n( network-object .+\n?)+', re.MULTILINE) group_match = group_pattern.search(config) if group_match: group_content = group_match.group() # 提取子网和掩码 subnet_pattern = re.compile(r' network-object (\d+\.\d+\.\d+\.\d+) (\d+\.\d+\.\d+\.\d+)') subnets = subnet_pattern.findall(group_content) print("提取的子网与掩码:") for ip, mask in subnets: print(f"IP: {ip}, 掩码: {mask}")
优化细节说明
- 使用
^和re.MULTILINE确保匹配行首的对象组头部,避免误匹配配置中其他位置的相似文本 - 将子网行的换行符改为
\n?,兼容配置末尾无换行的情况 - 方案2中单独拆分IP和掩码为分组,方便后续直接使用子网的各个组成部分
内容的提问来源于stack exchange,提问作者mlazzarotto91
相关产品推荐
相关产品推荐

