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

时间:2013-10-24 14:53:23

标签: php regex

我想将定义为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\/\._-]+) ?)+)将匹配我需要的值,但不会与单独的虚拟主机/集/数组匹配。

我无法将它们连接在一起。

2 个答案:

答案 0 :(得分:2)

它需要的代码比我最初想象的要多。请考虑以下代码:

$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
        )
)

答案 1 :(得分:0)

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