使用动态键和值创建嵌套字典

时间:2021-06-02 19:31:17

标签: python

这是我要修改的文字:

object-group network GRP_AM
 network-object 10.45.2.0 255.255.252.0
 network-object 10.1.224.0 255.255.224.0
object-group network TRA_ES1
 network-object 10.49.172.0 255.255.255.0
object-group network ACOTA
 network-object 10.194.192.0 255.255.192.0
object-group network BYATR
 network-object 10.49.143.0 255.255.255.0
 network-object 10.23.64.0 255.255.192.0
 network-object 10.49.149.0 255.255.255.0
object-group network LKHIO
 network-object 10.49.143.0 255.255.255.0
 network-object 10.194.64.0 255.255.192.0
 network-object 10.49.149.0 255.255.255.0
 network-object 10.21.143.0 255.255.255.0

这是我想要的输出:

create group "GRP_AM" 
 set objects "10.45.2.0" "10.1.224.0"

create group "TRA_ES1"
 set objects "10.49.172.0"

create group "ACOTA"
 set objects "10.194.192.0"

create group "BYATR"
 set objects "10.49.143.0" "10.23.64.0" "10.49.149.0"

create group "LKHIO"
 set objects "10.49.143.0" "10.194.64.0" "10.49.149.0" "10.21.143.0"

这是我目前的脚本,但不知道如何继续:

import re

text = """object-group network GRP_AM
 network-object 10.45.2.0 255.255.252.0
 network-object 10.1.224.0 255.255.224.0
object-group network TRA_ES1
 network-object 10.49.172.0 255.255.255.0
object-group network ACOTA
 network-object 10.194.192.0 255.255.192.0
object-group network BYATR
 network-object 10.49.143.0 255.255.255.0
 network-object 10.23.64.0 255.255.192.0
 network-object 10.49.149.0 255.255.255.0
object-group network LKHIO
 network-object 10.49.143.0 255.255.255.0
 network-object 10.194.64.0 255.255.192.0
 network-object 10.49.149.0 255.255.255.0
 network-object 10.21.143.0 255.255.255.0
 """

net_obj = ''
grp_name = ''
dict1 = {}

RE_OBJECT_GROUP = r"object-group network\s+(?P<re_grp_name>\S+$$)"
RE_NETWORK_OBJECT = r" network-object\s+(?P<re_addr>\S+)\s+(?P<re_mask>.*$$)"


for i in text.splitlines():

    match = re.search(RE_OBJECT_GROUP, i)
    if match:
        grp_name = match.group('re_grp_name').strip()                  
 
    match = re.search(RE_NETWORK_OBJECT, i)
    if match:
        net_obj = match.group('re_addr').strip()    
        
    dict1[grp_name] = {
        'Network': net_obj
        }  

for k in dict1:
    obj_name = dict1[k]['Network']
    result = f"create group \"{k}\"\n \
set object \"{obj_name}\"\n \
\n"
    print(result)

是否可以使用动态对象创建嵌套字典,以将网络对象添加为值而不覆盖它们?如果您认为有更好的方法可以做到这一点,那也将非常受欢迎。谢谢。

1 个答案:

答案 0 :(得分:0)

您可以通过收集创建每个嵌套目录所需的所有数据来执行您想要的操作,因为文本行是按顺序处理的。一种方法是使用简单的(两种状态)FSM (Finite-State Machine),如下图所示。我还将正在处理的文本包装在内存中的 StringIO 文本缓冲区中,以便通过 next() 函数从它流式传输行,就好像它是一个磁盘文件一样。

from pprint import pprint
import re
from io import StringIO


text = """object-group network GRP_AM
 network-object 10.45.2.0 255.255.252.0
 network-object 10.1.224.0 255.255.224.0
object-group network TRA_ES1
 network-object 10.49.172.0 255.255.255.0
object-group network ACOTA
 network-object 10.194.192.0 255.255.192.0
object-group network BYATR
 network-object 10.49.143.0 255.255.255.0
 network-object 10.23.64.0 255.255.192.0
 network-object 10.49.149.0 255.255.255.0
object-group network LKHIO
 network-object 10.49.143.0 255.255.255.0
 network-object 10.194.64.0 255.255.192.0
 network-object 10.49.149.0 255.255.255.0
 network-object 10.21.143.0 255.255.255.0
"""

RE_OBJECT_GROUP = re.compile(r"object-group network\s+(?P<re_grp_name>\S+$$)")
RE_NETWORK_OBJECT = re.compile(r" network-object\s+(?P<re_addr>\S+)\s+(?P<re_mask>.*$$)")

dict1 = {}
with StringIO(text) as lines:
    line = next(lines)
    state = 1
    while True:
        if state == 1:
            match = RE_OBJECT_GROUP.search(line)
            if not match:
                break
            grp_name = match.group('re_grp_name').strip()
            line = next(lines)
            state = 2
        elif state == 2:
            net_objects = []
            while True:
                match = RE_NETWORK_OBJECT.search(line)
                if not match:
                    break
                net_objects.append(match.group('re_addr').strip())
                try:
                    line = next(lines)
                except StopIteration:
                    break
            if net_objects:
                dict1[grp_name] = {'Network': net_objects}
            state = 1

pprint(dict1, width=90, sort_dicts=False)

漂亮的打印输出:

{'GRP_AM': {'Network': ['10.45.2.0', '10.1.224.0']},
 'TRA_ES1': {'Network': ['10.49.172.0']},
 'ACOTA': {'Network': ['10.194.192.0']},
 'BYATR': {'Network': ['10.49.143.0', '10.23.64.0', '10.49.149.0']},
 'LKHIO': {'Network': ['10.49.143.0', '10.194.64.0', '10.49.149.0', '10.21.143.0']}}