Я хочу сопоставить значения, определенные как 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"; } } }