正则表达式匹配来自 Apache 虚拟主机文件的特定值


Regex to match specific values from from an Apache virtualhost file

我想将定义为ServerNameServerAliasDocumentRoot的值与正则表达式匹配。

可以忽略具有前面#的任何内容。

我还想将每个虚拟主机的定义分开,因此在下面的示例中,我将有两个数组。

例:

<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";
    }
  }
}