我有一个问题,我的正则表达式匹配太多。我试过让它尽可能不贪婪。我的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/
上进行测试答案 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 host
和HOST_B
之间没有右括号。试试这个(未经测试):
define host\s*{[^}]HOST_B.*?}
(确保使用标记允许.
匹配换行符。)