0

我有一个问题,我的正则表达式匹配太多。我已经尝试让它尽可能不贪婪。我的RE是:

 define host( |\t)*{(.*\n)*?( |\t)*host_name( |\t)*HOST_B(.*\n)*?( |\t)*}

意义

“定义主机”后跟任何空格或制表符,后跟“{”。任何文本和换行符,直到任意数量的空格或制表符后跟“host_name”,然后是任意数量的空格或制表符,后跟“HOST_B”。任何文本加上换行符,直到任何空格或制表符后跟“}”

我的文字是

define host{
    field stuff
        }

define timeperiod{
        sunday          00:00-03:00,07:00-24:00
        }

define stuff{
        hostgroup_name                  things
        service_description             load
        dependent_service_description   cpu_util
        execution_failure_criteria      n
        notification_failure_criteria   w,u,c
        }

define host{
        use                     things
        host_name               HOST_A
        0alias                  stuff 
       }

define host{
        use                     things
        host_name               HOST_B
        alias                   ughj
        address                 1.6.7.6
       }

define host{
        use                     things
        host_name               HOST_C
       }

匹配从第一个定义到 host_b 的结束括号。它没有得到 host_c 的组(它不应该得到 host_c),但是我只想要主机 b 的组而不是整个事情。

有什么帮助吗?我的正则表达式生锈了。您可以在http://regexpal.com/上进行测试

4

3 回答 3

1

这与您要求的有点不同,但我认为您可能会喜欢结果。这将解析所有结构并将它们加载到 python 字典中。从那里开始,操作对您来说应该非常好和容易。

mDefHost = re.findall(r"\define host{(.*?)\}",a,re.S)
mInHost  = re.compile("(\S+)\s+(\S+)")
hostDefs = []

for item in mDefHost:
    hostDefs.append( dict(mInHost.findall(item)) )

前输出

>>> m = re.findall(r"define host\{(.*?)\}",a,re.S)
>>> m
['\n        use                     things\n        host_name               HOST_B\n            alias                   ughj\n        address                 1.6.7.6\n       ']
>>> item = m[0]
>>> item
'\n        use                     things\n        host_name               HOST_B\n            alias                   ughj\n        address                 1.6.7.6\n       '
>>> results = re.findall("(\S+)\s+(\S+)",item)
>>> results
[('use', 'things'), ('host_name', 'HOST_B'), ('alias', 'ughj'), ('address', '1.6.7.6')]
>>> dict(results)
{'alias': 'ughj', 'use': 'things', 'host_name': 'HOST_B', 'address': '1.6.7.6'}
于 2013-02-14T17:00:58.697 回答
1

问题是您正在使用正则表达式搜索整个字符串,但您试图找到一个子字符串,该子字符串的开头与整个字符串的开头无法区分。你不能使用非贪心匹配来确保你的起点尽可能晚;非贪婪修饰符影响则表达式引擎寻找匹配项的距离。

您需要确保在您的define host和您的HOST_B. 试试这个(未经测试):

define host\s*{[^}]HOST_B.*?}

(确保使用标志来允许.匹配换行符。)

于 2013-02-14T17:18:41.867 回答
1

我还没有测试过,但我想你需要用 [^{]* 删除 .*。这样你的正则表达式就不会吃下一个“{”。

这对我来说看起来很奇怪:(.*\n)*? 看看 DOTALL:如果你设置这个标志,点就会吃换行符。

于 2013-02-14T16:19:29.383 回答