You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在正则捕获组中排除特定文本?以Cisco ACL解析为例

问题:在正则层面提取Cisco ACL协议时移除"object-group"前缀

现有Cisco ACL条目

access-list office extended permit tcp host 1.1.1.1 host 2.2.2.2
access-list home extended permit object-group PROTOS4 host 4.4.4.4 host 5.5.5.5

现有Python解析代码

import re

acl_general_structure = (
    r'access-list\s+(?P<policy_name>[A-Za-z0-9\-\_]+)\s+extended\s+(?P<action>permit|deny)'
    r'\s'
    r'(?P<protocol>[a-zA-Z0-9]+|(?:object-group\s[A-Za-z\d]+))'
    r'\s'
    r'host\s(?P<source>(?:[0-9]{1,3}\.){3}[0-9]{1,3})'
    r'\s'
    r'host\s(?P<destination>(?:[0-9]{1,3}\.){3}[0-9]{1,3})'
)

f_in_name="xx.config"
f_out_name=f_in_name + ".csv"

with open(f_in_name, "r", encoding="utf8") as f:
    for line in f.readlines():
        result=re.match(acl_general_structure,line)
        if result:
            print(result.groupdict())

当前输出

{'policy_name': 'office', 'action': 'permit', 'protocol': 'tcp', 'source': '1.1.1.1', 'destination': '2.2.2.2'}
{'policy_name': 'home', 'action': 'permit', 'protocol': 'object-group PROTOS4', 'source': '4.4.4.4', 'destination': '5.5.5.5'}

期望输出

{'policy_name': 'office', 'action': 'permit', 'protocol': 'tcp', 'source': '1.1.1.1', 'destination': '2.2.2.2'}
{'policy_name': 'home', 'action': 'permit', 'protocol': 'PROTOS4', 'source': '4.4.4.4', 'destination': '5.5.5.5'}

解决方案:在正则层面实现需求

可以直接通过修改正则表达式的protocol捕获组来实现,不需要后续字符串处理。核心思路是拆分两个匹配分支:

  • 分支1:匹配普通协议字符串(如tcp),直接捕获到protocol组
  • 分支2:先匹配object-group (不捕获该前缀),再将后面的组名捕获到同一个protocol组

修改后的正则表达式如下:

import re

acl_general_structure = (
    r'access-list\s+(?P<policy_name>[A-Za-z0-9\-\_]+)\s+extended\s+(?P<action>permit|deny)'
    r'\s'
    r'(?:(?P<protocol>[a-zA-Z0-9]+)|object-group\s(?P<protocol>[A-Za-z\d]+))'
    r'\s'
    r'host\s(?P<source>(?:[0-9]{1,3}\.){3}[0-9]{1,3})'
    r'\s'
    r'host\s(?P<destination>(?:[0-9]{1,3}\.){3}[0-9]{1,3})'
)

f_in_name="xx.config"
f_out_name=f_in_name + ".csv"

with open(f_in_name, "r", encoding="utf8") as f:
    for line in f.readlines():
        result=re.match(acl_general_structure,line)
        if result:
            print(result.groupdict())

关键修改说明

  • 使用(?:...)创建非捕获组包裹两个分支,确保正则整体结构不受影响
  • 第一个分支(?P<protocol>[a-zA-Z0-9]+)直接捕获普通协议名
  • 第二个分支object-group\s(?P<protocol>[A-Za-z\d]+)中,object-group\s仅做匹配不捕获,真正的组名被捕获到protocol组中

修改后运行输出

{'policy_name': 'office', 'action': 'permit', 'protocol': 'tcp', 'source': '1.1.1.1', 'destination': '2.2.2.2'}
{'policy_name': 'home', 'action': 'permit', 'protocol': 'PROTOS4', 'source': '4.4.4.4', 'destination': '5.5.5.5'}

完全符合期望输出,无需额外处理字典中的protocol值。


内容的提问来源于stack exchange,提问作者Dione Saturn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 13:20:18