(Python) 从 Cisco 配置中提取网络对象组的正则表达式

问题描述 投票:0回答:3

我想使用 Python 和正则表达式从 Cisco 配置中提取网络组。 该组以

object-group network Cloudflare
开头,紧接着,有一个或多个子网,如
 network-object 173.245.48.0 255.255.240.0
。 文字将是

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

使用此正则表达式时

(?P<name>object-group network Cloudflare)\n(?P<subnets> network-object \d+\.\d+\.\d+\.\d+ \d+\.\d+\.\d+\.\d+\n)*
我得到 3 个匹配组,其中只有第一个可用,但它包含标题
object-group ...
。 可以改进吗? https://regex101.com/r/s925cq/1

python regex
3个回答
1
投票
data = """
 network-object 1.1.1.1 0.0.0.0
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
access-list outside
"""

regex=r"object-group network (?P<network>\S+)|network-object\s(?P<subnet>\S+?)\s(?P<mask>\S+)"
matches = re.finditer(regex, data)
result = []
network_group = {"network": "Unknown"}


for cnt, match in enumerate(matches):
    info = match.groupdict()
    info1 = {k: v for k, v in info.items() if v is not None}
    if check:=info.get("network"):
        network_group =   {"network": check} if check else network_group
    if not info.get("network"):
        result.append(network_group | info1)
result

enter image description here


1
投票

您可以使用以下命令获取命名组子网中的所有网络对象:

(?P<name>object-group network Cloudflare)\n(?P<subnets>(?: network-object (?:\d+\.){3}\d+ (?:\d+\.){3}\d+\n)+)

解释

  • (?P<name>object-group network Cloudflare)
    命名组名称,字面匹配
  • \n
    匹配换行符
  • (?P<subnets>
    命名组 子网
    • (?:
      非捕获组作为整体重复
      • network-object
      • (?:\d+\.){3}\d+ (?:\d+\.){3}\d+\n
        匹配 2 次数字,点部分后跟换行符
    • )+
      关闭非捕获组并重复 1 次或多次(以匹配至少 1 行)
  • )
    关闭组子网

查看 regex 101 演示


0
投票

简介

正如@Ted Lyngmo提到的上面,最好使用特定于这种网络配置格式的解析器。 一旦这样的解析器是ciscoconfparse2(尽管有这个名字,它读取的内容比思科配置文件要多)。

使用 ciscoconfparse2 相对于原始正则表达式的优点是代码更具可读性和可维护性。

使用 ciscoconfparse2

的正则表达式技术

要获取

object-group network Cloudflare
中的子网列表,请使用 ciscoconfparse2 读取格式并构建一个字典来保存网络。 您可以使用以下技术阅读无限的
object-group
语句。

使用 ciscoconfparse2 这非常简单...

from pprint import pprint

from ciscoconfparse2 import CiscoConfParse, IPv4Obj

config = """
 network-object 1.1.1.1 0.0.0.0
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
access-list outside
"""

parse = CiscoConfParse(config)

# Store all object-group names in a dict to list mapping
#    key the dict by the object-group name and append the networks to each
object_groups = dict()

# If there are multiple object-groups, iterate over each one...
for object_group_cmd in parse.find_objects('^object-group'):
    name = object_group_cmd.split()[2]

    # Grab all object-group network-object commands at once with this regex...
    networks = object_group_cmd.re_list_iter_typed('network-object\s+(\d.+)')

    object_groups[name] = list()
    for cmd in networks:

        tmp = cmd.split()
        network, netmask = tmp[0], tmp[1]

        # Add each network and netmask to the list...
        object_groups[name].append({'network': network, 'netmask': netmask})

pprint(object_groups)

将打印:

{'Cloudflare': [{'netmask': '255.255.240.0', 'network': '173.245.48.0'},
                {'netmask': '255.255.252.0', 'network': '103.21.244.0'},
                {'netmask': '255.255.252.0', 'network': '103.22.200.0'},
                {'netmask': '255.255.252.0', 'network': '103.31.4.0'},
                {'netmask': '255.255.192.0', 'network': '141.101.64.0'},
                {'netmask': '255.255.192.0', 'network': '108.162.192.0'},
                {'netmask': '255.255.240.0', 'network': '190.93.240.0'},
                {'netmask': '255.255.240.0', 'network': '188.114.96.0'},
                {'netmask': '255.255.252.0', 'network': '197.234.240.0'},
                {'netmask': '255.255.128.0', 'network': '198.41.128.0'},
                {'netmask': '255.254.0.0', 'network': '162.158.0.0'},
                {'netmask': '255.248.0.0', 'network': '104.16.0.0'},
                {'netmask': '255.252.0.0', 'network': '104.24.0.0'},
                {'netmask': '255.248.0.0', 'network': '172.64.0.0'},
                {'netmask': '255.255.252.0', 'network': '131.0.72.0'}]}

应该注意的是,这会立即获取所有

object-group network
语句...

© www.soinside.com 2019 - 2024. All rights reserved.