python解析绑定配置与嵌套花括号

时间:2014-02-17 14:38:25

标签: python regex parsing

我正在尝试自动解析现有绑定配置,其中包含多个这些区域定义:

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

请注意mastersallow-transfer中的元素数量可能会有所不同。我尝试使用re.split()分割它,并且由于嵌套的花括号而失败了。

我的目标是每个条目的字典。

提前感谢您的帮助!

2 个答案:

答案 0 :(得分: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_dict将返回区域定义字典。每个区域定义都将域/ url作为其密钥。区域定义中的每个键/值都是一个字符串。

这是上例的输出:

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

如果您要使用关键字“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"'}}

您必须进一步剥离以使其更具可读性。

答案 1 :(得分:2)

一种方法是(安装和)使用正则表达式模块而不是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

相关问题