首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用dhcpd.conf解析textX

用dhcpd.conf解析textX
EN

Stack Overflow用户
提问于 2018-11-19 17:33:47
回答 1查看 665关注 0票数 1

我使用https://github.com/igordejanovic/textX解析dhcpd.conf文件(不,https://pypi.org/project/iscconf/不工作,它会崩溃在我的dhcpd.conf文件上),特别是提取具有固定地址的主机。

记录如下:

代码语言:javascript
复制
    host example1 {
    option host-name "example1";
    ddns-hostname "example1";
    fixed-address 192.168.1.181;
    }

    host example2 {
    hardware ethernet aa:bb:ff:20:fa:13;
    fixed-address 192.168.1.191;
    option host-name "example2";
    ddns-hostname "example2";
    }

代码:

代码语言:javascript
复制
def get_hosts(s):
    grammar = """
    config: hosts*=host ;

    host: 'host' hostname=ID '{'
        (
            ('hardware ethernet' hardware_ethernet=/[0-9a-fA-F:]+/';')?

            'fixed-address' fixed_address=/([0-9]{1,3}\.){3}[0-9]{1,3}/';'

            ('option host-name' option_host_name=STRING';')?

            ('ddns-hostname' ddns_hostname=STRING';')?
        )#
    '}'
    ;
    """
    mm = metamodel_from_str(grammar)
    model = mm.model_from_str(s)
    for host in model.hosts:
        print host.hostname, host.fixed_address

现在,我不能用这个语法来解析整个dhcpd.conf (显然,我得到了语法错误,因为文件中有太多其他元素而语法没有说明);另一方面,我不想为这个文件构造完整的语法,因为我只需要提取特定类型的主机记录。

我当然可以使用正则表达式提取主机记录并分别解析它们,但是我想知道是否有什么方法可以让textX只从文件中提取host记录,而忽略其余的内容呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-19 20:03:34

这里是textX作者。我不是SO的常客。)你可以玩regex匹配和regex的外观来消耗不必要的内容。下面是一个完整的示例,它正确地处理中间文本,即使有关键字host。如果前面没有单词host,规则host首先会消耗一个字符,这是由于零或多个操作符造成的。当我们得到一个单词host时,我们尝试匹配host规则一次或多次,并收集所有的宿主对象,如果该规则没有成功至少一次(注意+=的使用),我们使用word host并重复这个过程。这可能会做得更好(更有表现力),但你明白了。在做这类事情时,知道textX默认使用空白空间是件好事,但您可以使用noskipws (请参阅医生们)将其关闭,无论是全局的还是按规则的。

代码语言:javascript
复制
from textx import metamodel_from_str


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

    host: 'host' hostname=ID '{'
        (
            ('hardware ethernet' hardware_ethernet=/[0-9a-fA-F:]+/';')?
            'fixed-address' fixed_address=/([0-9]{1,3}\.){3}[0-9]{1,3}/';'
            ('option host-name' option_host_name=STRING';')?
            ('ddns-hostname' ddns_hostname=STRING';')?
        )#
    '}'
    ;
    """
    conf_file = r"""
    host example1 {
    option host-name "example1";
    ddns-hostname "example1";
    fixed-address 192.168.1.181;
    }

    some arbitrary content in between
    with word host but that fails to match host config.

    host example2 {
    hardware ethernet aa:bb:ff:20:fa:13;
    fixed-address 192.168.1.191;
    option host-name "example2";
    ddns-hostname "example2";
    }
    """
    mm = metamodel_from_str(grammar)
    model = mm.model_from_str(conf_file)
    assert len(model.hosts) == 2
    for host in model.hosts:
        print(host.hostname, host.fixed_address)


if __name__ == "__main__":
    test_get_hosts()

编辑:这里还有两个关于config规则的想法:一个简单的:

代码语言:javascript
复制
config: ( hosts+=host | /./ )* ;

并且(可能)在尝试host之前使用regex引擎消耗尽可能多的性能。

代码语言:javascript
复制
config: ( /(?s:.*?(?=host))/ hosts*=host | 'host' )*
        /(?s).*/;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53379893

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档