парсинг — PHP создает массив из текстового шаблона (файл cfg)

поэтому у меня есть пара файлов Nagios CFG для служб, хостов, контактов и т. д.

Я хочу проанализировать эти файлы CFG с PHP для обработки данных.

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, они содержат больше, чем эти три определения … Может быть, с помощью regex или preg_match …?

0

Решение

почти в каждом полусложном языке (в данном случае в вашей конфигурации) синтаксический анализ с помощью регулярных выражений, которые соответствуют более чем одному токену, имеет некоторые крайние случаи, когда он завершится неудачно.

Предположим, вы примете наивный подход и проанализируете определение объекта с помощью

/define\s+([^\s]+){([^}]*)}/

это будет соответствовать каждой предоставленной вами контактной группе или предоставленному сервису и введет тип \1 и содержание в \2, Однако, если есть # спереди, вам придется отфильтровать это. Так что вы, вероятно, должны циклически перебирать все строки и удалять строки комментариев, до вы начинаете сопоставлять определения объектов.

После этого вы заметите, что есть больше комментариев, например, ; commentтак что вы бы тоже отфильтровали. Я не знаю много о разрешенных символах, но если какое-то значение может где-то содержать } ты в беде.

Если это не так, вы, вероятно, могли бы использовать первое предоставленное регулярное выражение, а не разбивать содержимое на строки и preg_split каждая строка внутри определения объекта с

/^\s*([^\s]+)\s+(.*)$/

где ключ в \1 и значение в \2, но значение, вероятно, должно быть trimредактор

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]