我想将定义为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";
}
}
}