PHP从文本模式生成数组(cfg文件)

时间:2016-07-25 21:09:07

标签: php parsing nagios

所以我有几个Nagios CFG文件,用于服务,主机,联系人等

我想用PHP解析这些CFG文件来处理数据。

ContactGroups.CFG

define contactgroup {
     contactgroup_name       VAP3
     alias                   VAP3_PRE
     members                 userz, userw }

define contactgroup {
     contactgroup_name       VAP4
     alias                   VAP4_PUSH
     members                 userx, usery }

Services.CFG

define service {
    host_name                       HostA
    service_description             HostA_HD
    contact_groups                  VAP2,VAP3 }

define service {
    host_name                       HostB
    service_description             HostB_HD
    contact_groups                  VAP3,VAP4 }

所以我想解析它:

contactgroup_name[0] = "VAP3";
alias[0] = "VAP3_PRE";
members [0] = "userz,userw";

contactgroup_name[1] = "VAP4";
alias[1] = "VAP4_PUSH";
members [1] = "userx, usery";

对于服务文件:

host_name [0] = "HostA";
service_description [0] = "HostA_HD";
contact_groups [0] = "VAP2,VAP3";

host_name [1] = "HostB";
service_description [1] = "HostB_HD";
contact_groups [1] = "VAP3,VAP4";

所以我可以在我的PHP脚本中轻松地像数组一样处理它,这些只是CFG文件的一个例子,它们包含的不仅仅是这三个定义...也许使用正则表达式或preg_match ......?

1 个答案:

答案 0 :(得分:0)

在几乎所有半复杂的语言中(在这种情况下是你的配置),通过匹配多个令牌的正则表达式进行解析会有一些边缘情况会失败。

假设您将采用天真的方法并使用

解析对象定义
/define\s+([^\s]+){([^}]*)}/

这将匹配您提供的每个联系人组或服务示例,并将类型放在\1中,将内容放在\2中。但是,如果前面有#,则必须将其过滤掉。所以你应该循环遍历所有行并删除注释行,之前开始匹配对象定义。

之后您会注意到,允许更多评论,例如; comment,因此您也会过滤掉。我不太了解允许的字符,但如果某个地方的某些值可能有效地包含},那么您就会陷入困境。

如果情况并非如此,您可以使用提供的第一个正则表达式,而不是使用

将内容拆分为行和preg_split对象定义中的每一行。
/^\s*([^\s]+)\s+(.*)$/

其中密钥位于\1且值为\2,但该值可能为trim