正则表达式转换为对象

regex convert to object

我正在尝试获取以下正则表达式的值:

from textx import metamodel_from_str


def test_get_hosts2():
    grammar = r"""
    config: ( /(?!host)./ | hosts+=host | 'host' )* ;

    host: 'host' host2name=/[0-9a-zA-Z.-]+/ '{'
        (
            'fixed-address' fixed_address=/([0-9]{1,3}\.){3}[0-9]{1,3}/';'
            ('option host-name' option_host_name=STRING';')?
            ('option domain-name-servers' option_domain_name_servers=/([0-9]{1,3}\.){3}[0-9]{1,3}, ([0-9]{1,3}\.){3}[0-9]{1,3}/';')?
            ('option netbios-name-servers' option_netbios_name_servers=/([0-9]{1,3}\.){3}[0-9]{1,3}/';')?
            ('option domain-name' option_domain_name=STRING';')?
        )#
    '}'
    ;
    """

    conf_file = r"""
    host corehost.abc.abc.ab {
    fixed-address 172.124.106.10;
    option host-name "hostname.abc.abc.ab";
    option domain-name-servers 123.123.123.120, 123.123.128.142;
    option netbios-name-servers 172.124.106.156;
    option domain-name "abcm1.abc.abc.ab";
    option domain-search "abcm1.abc.abc.ab", "abcmo2.abc.abc.ab", "abcmo.3abc.abc.ab", "abcmo4.abc.abc.ab";
    }

    host corehost2.abc.abc.ab {
    fixed-address 172.124.106.120;
    option host-name "hostname2.abc.abc.ab";
    option domain-name-servers 123.123.123.220, 123.123.128.242;
    option netbios-name-servers 172.124.106.256;
    option domain-name "abcm2.abc.abc.ab";
    option domain-search "abcm2.abc.abc.ab", "abcmo2.abc.abc.ab", "abcm.3abc.abc.ab", "abcm4.abc.abc.ab";
    }

    """
    mm = metamodel_from_str(grammar)
    model = mm.model_from_str(conf_file)
    print(model.hosts)
    # assert len(model.hosts) == 2
    for host in model.hosts:
        print(host)
        print(host.host2name, host.fixed_address, host.option_domain_name_servers, host.option_domain_search)


if __name__ == "__main__":
    test_get_hosts2()

但我可以获得唯一的单个值,例如“固定地址”和“主机名”。在“域名服务器”中,我在正则表达式中使用了“,”。但我认为这不是正确的方法,因为值不相同。你能帮我用正确的正则表达式得到“domain-name-servers”和“domain-search”的值吗?

参考:

最简单的方法是使用 textX 的 repetition modifiers 来匹配 comma-separated 值的序列。基本上,无论何时匹配 zero-or-more 或 one-or-more 等,您都可以在方括号中添加修饰符。最常用的修饰符是分隔符修饰符,它基本上是在每两个元素之间使用的匹配。

另一方的好处是:

  • 简单(更易于维护)
  • 您会得到一个很好的 Python 元素列表,因此您不需要进一步处理匹配的字符串。

工作语法是(注意 +[','] 的使用,这意味着 one-or-more with a comma as a separator):

    config: ( /(?!host)./ | hosts+=host | 'host' )* ;

    host: 'host' host2name=/[0-9a-zA-Z.-]+/ '{'
        (
            'fixed-address' fixed_address=ip_addr';'
            ('option' 'host-name' option_host_name=STRING';')?
            ('option' 'domain-name-servers' option_domain_name_servers=ip_addr+[',']';')?
            ('option' 'netbios-name-servers' option_netbios_name_servers=ip_addr+[',']';')?
            ('option' 'domain-name' option_domain_name=STRING+[',']';')?
            ('option' 'domain-search' option_domain_search=STRING+[',']';')?
        )#
    '}';

    ip_addr: /([0-9]{1,3}\.){3}[0-9]{1,3}/;