2017-08-08 36 views
0

我想解析一个Nagios/Icinga配置,所以我可以用Python对它进行进一步处理。由于我找不到工作库来做到这一点(pynag似乎根本无法工作),我正在尝试使用正则表达式编写一个简单的Python脚本。用Python解析Nagios/Icinga配置正则表达式

基本上我想从这个CONFIGFILE得到(它使用缩进选项卡):

define host { 
    address 123.123.123.123 
    passive_checks_enabled 1 
    } 

define service { 
    service_description Crondaemon 
    check_command check_nrpe_1arg!check_crondaemon 
    } 

到像这样的Python元组:

(
('host', ('address', '123.123.123.123'), ('passive_checks_enabled', '1')), 
('service', ('service_description', 'Crondaemon'), ('check_command', 'check_nrpe_1arg!check_crondaemon')) 
) 

这是我与分析逻辑完整的脚本,包括一个例子来测试:

import re 

# white spaces are tabs! 
TEST_STR = """ 
define host { 
    address 123.123.123.123 
    passive_checks_enabled 1 
    } 

define service { 
    service_description Crondaemon 
    check_command check_nrpe_1arg!check_crondaemon 
    } 
""" 

cfg_all_regex = re.compile(
    r'define\s+(\w+)\s*\{' 
    '(.*?)' 
    '\t}', 
    re.DOTALL 
) 
# basic regex works 
print(re.findall(cfg_all_regex, TEST_STR)) 

cfg_all_regex = re.compile(
    r'define\s+(\w+)\s*{\n' 
    '(\t(.*)?\t(.*)?\n)*' 
    '\t}', 
    re.DOTALL 
) 
# more specific regex to extract all key values fails 
print(re.findall(cfg_all_regex, TEST_STR)) 

不幸的是,我不能得到完整的解析工作,它总是匹配一切或没有。 你能给我一个提示如何修复我的正则表达式,所以我可以从我的Icinga配置中提取所有的键值对吗?

回答

1

重模块不支持重复捕捉,所以

'(\t(.*)?\t(.*)?\n)*' 

只保留了最后一组拍摄。

同样我会改变这个像

'\t(\w+)\s+([^\n]*)\n\' 

因此,一个可能的解决方案,给您的数据的结构,可以创建一个正则表达式将匹配模式:

regex = r'define\s+(\w+)\s+\{\n|\t(\w+)\s+([^\n]*)\n|\t\}' 
matches = re.finditer(regex, TEST_STR, re.DOTALL) 

随着for循环可以遍历组

for match in matches: 
    for groupNum in range(0, len(match.groups())): 
     groupNum = groupNum + 1 
     if match.group(groupNum): 
      print("Group {}: {}".format(groupNum, match.group(groupNum))) 

return:

Group 1: host 
Group 2: address 
Group 3: 123.123.123.123 
Group 2: passive_checks_enabled 
Group 3: 1 
Group 1: service 
Group 2: service_description 
Group 3: Crondaemon 
Group 2: check_command 
Group 3: check_nrpe_1arg!check_crondaemon 
+0

哇,没想到这不能用简单的正则表达式解决。但是你的解决方案就像一个魅力,我可以完成我的解析器。最终的逻辑可以在这里找到:https://gist.github.com/ifischer/6e8aa105c5f644fd3803f8b41dcbe4f3 非常感谢你的帮助,节省了我很多时间摆弄! – ifischer

+1

刚刚发现[regex](https://pypi.python.org/pypi/regex/)支持重复捕获。也许这个解决方案可以简化很多。但现在不值得努力 – ifischer

+0

你是对的。如果在项目中安装第三方库是可行的,则正则表达式模块是更好的选择。 – alvarez