Regex для соответствия определенным значениям из файла виртуального хоста Apache

Я хочу сопоставить значения, определенные как ServerName , ServerAlias и DocumentRoot с регулярным выражением.

Любое с предыдущим # можно игнорировать.

Я также хотел бы, чтобы описания каждого виртуального хоста были разделены, поэтому в приведенном ниже примере у меня будет два массива.

Пример:

 <VirtualHost *:80> ServerName foo.com ServerAlias stage.foo.com new.foo.com DocumentRoot /var/www/foo.com </VirtualHost> <VirtualHost *:80 *:443> ServerName bar.com ServerAlias store.bar.com #ServerAlias new.bar.com us.bar.com DocumentRoot /var/www/bar.com </VirtualHost> 

Моя работа:

<VirtualHost(?: \*\:[0-9]*)+>\s* будет совпадать с каждым тегом виртуального хостинга с добавлением пробела.

[^\#](?:ServerName|ServerAlias|DocumentRoot) ((?:(?:[\w\/\._-]+) ?)+) Будет соответствовать требуемым значениям, но не как отдельные виртуальные хосты / наборы / массивы.

У меня проблемы с их соединением.

Это потребовало большего количества кода, чем я думал изначально. Рассмотрим этот код:

 $s = <<< EOF <VirtualHost *:80> ServerName foo.com ServerAlias stage.foo.com new.foo.com DocumentRoot /var/www/foo.com </VirtualHost> <VirtualHost *:80 *:443> ServerName bar.com ServerAlias store.bar.com #ServerAlias new.bar.com us.bar.com DocumentRoot /var/www/bar.com </VirtualHost> EOF; $vh = array(); if (preg_match_all('~<VirtualHost ([^>]+)>(.+?)</VirtualHost>~is', $s, $arr)) { for($i=0; $i < count($arr[1]); $i++) { if (preg_match_all('/^ *(ServerName|ServerAlias|DocumentRoot) +(.+)$/im', $arr[2][$i], $m)) { $entries = array(); for($j=0; $j < count($m[1]); $j++) $entries[$m[1][$j]] = $m[2][$j]; $vh[$arr[1][$i]] = $entries; } } } print_r($vh); 

ВЫВОД:

 Array ( [*:80] => Array ( [ServerName] => foo.com [ServerAlias] => stage.foo.com new.foo.com [DocumentRoot] => /var/www/foo.com ) [*:80 *:443] => Array ( [ServerName] => bar.com [ServerAlias] => store.bar.com [DocumentRoot] => /var/www/bar.com ) ) 

Вот версия perl:

 $in = 0; while ($line = <>) { if ($line =~ m/<VirtualHost(?: \*\:[0-9]*)+>\s*/) { $in = 1; } if ($line =~ m/<\/VirtualHost>/) { $in = 0; } if ($in eq 1) { if (!($line =~ m/#/) && $line =~ m/(?:ServerName|ServerAlias|DocumentRoot) ((?:(?:[-\w\/.]+) ?)+)/) { print $1; print "\n"; } } }