python解析带嵌套大括号的绑定配置

2024-06-16 13:04:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试自动解析现有的绑定配置,该配置由多个区域定义组成:

zone "domain.com" {
        type slave;
        file "sec/domain.com";
        masters {
                11.22.33.44;
                55.66.77.88;
        };
        allow-transfer {
             "acl1";
             "acl2";
        };
};  

请注意,masters和{}中元素的数量可能不同。我尝试过用re.split()来拆分它,但由于嵌套的大括号,失败得很惨。在

我的目标是为每一个条目编写一本词典。在

提前感谢您的帮助!在


Tags: com区域zone元素定义domaintypesec
2条回答

这就可以了,其中“st”是所有区域定义的字符串:

import re
zone_def = re.split('zone', st, re.DOTALL)
big_dict = {}
for zone in zone_def:
    if len(zone) > 0:
        zone_name = re.search('(".*?")', zone)
        sub_dicts = re.finditer('([\w]+) ({.*?})', zone, re.DOTALL)
        big_dict[zone_name.group(1)] = {}
        for sub_dict in sub_dicts:
            big_dict[zone_name.group(1)][sub_dict.group(1)] = sub_dict.group(2).replace(' ', '')
        sub_types = re.finditer('([\w]+) (.*?);', zone)
        for sub_type in sub_types:
            big_dict[zone_name.group(1)][sub_type.group(1)] = sub_type.group(2)

big-tu-dict将返回一个区域定义字典。每个区域定义都将域/url作为其键。区域定义中的每个键/值都是字符串。在

这是上述示例的输出:

^{pr2}$

如果你有第二个相同的区域,这是输出sssss.com网站". 在

{'"sssss.com"': {'transfer': '{\n"acl1";\n"acl2";\n}', 'masters': '{\n11.22.33.44;\n55.66.77.88;\n}', 'type': 'slave', 'file': '"sec/domain.com"'},'"domain.com"': {'transfer': '{\n"acl1";\n"acl2";\n}', 'masters': '{\n11.22.33.44;\n55.66.77.88;\n}', 'type': 'slave', 'file': '"sec/domain.com"'}}

您将不得不做一些进一步的剥离,使其更具可读性。在

一种方法是(安装并)使用regex模块而不是re模块。问题是re模块无法处理未定义的嵌套方括号级别:

#!/usr/bin/python
import regex
data = '''zone "domain.com" {
    type slave;
    file "sec/domain.com";
    masters {
        11.22.33.44; { toto { pouet } glups };
        55.66.77.88;
    };
    allow-transfer {
        "acl1";
        "acl2";
    };
};  '''

pattern = r'''(?V1xi)
(?:
    \G(?<!^)
  |
    zone \s (?<zone> "[^"]+" ) \s* {
) \s*
(?<key> \S+ ) \s+
(?<value> (?: ({ (?> [^{}]++ | (?4) )* }) | "[^"]+" | \w+ ) ; )
'''

matches = regex.finditer(pattern, data)

for m in matches:
    if m.group("zone"):
        print "\n" + m.group("zone")
    print m.group("key") + "\t" + m.group("value")

您可以通过以下链接找到有关此模块的更多信息:https://pypi.python.org/pypi/regex

相关问题 更多 >