大多数非贪婪的正则表达式在python中匹配(或者只是简单的正则表达式

时间:2013-02-14 16:15:05

标签: python regex pattern-matching non-greedy

我有一个问题,我的正则表达式匹配太多。我试过让它尽可能不贪婪。我的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/

上进行测试

3 个答案:

答案 0 :(得分:1)

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

这对我来说很奇怪:(.*\n)*? 看看DOTALL:如果设置此标志,则点会占用换行符。

答案 1 :(得分: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)) )

ex output

>>> 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'}

答案 2 :(得分:1)

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

您需要确保在define hostHOST_B之间没有右括号。试试这个(未经测试):

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

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