2016-11-02 4 views
1

Ich mag würde jede meiner virtuellen Hosts Konfigurationen greifen und sie in einem Array setzen mit preg_match_all so kann ich Informationen von jedem von ihnen extrahieren, zum Beispiel ...preg_match_all zwischen dynamischen Tags

$vHostConfig = ' <VirtualHost *:80> 
     ServerName localhost 
     DocumentRoot c:/wamp/www 
     <Directory "c:/wamp/www/"> 
      Options +Indexes +Includes +FollowSymLinks +MultiViews 
      AllowOverride All 
      Require local 
     </Directory> 
    </VirtualHost> 
    <VirtualHost *:8080> 
     ServerName testing.com 
     DocumentRoot c:/wamp/www/testing.com 
     <Directory "c:/wamp/www/testing.com"> 
      Options +Indexes +Includes +FollowSymLinks +MultiViews 
      AllowOverride All 
      Require local 
     </Directory> 
    </VirtualHost> 
    <VirtualHost 127.0.0.1:80> 
     ServerName testing2.com 
     DocumentRoot c:/wamp/www/testing2.com 
     <Directory "c:/wamp/www/testing2.com"> 
      Options +Indexes +Includes +FollowSymLinks +MultiViews 
      AllowOverride All 
      Require local 
     </Directory> 
    </VirtualHost> 
# <VirtualHost *:80> 
#  ServerName testing3.com 
#  DocumentRoot c:/wamp/www/testing3.com 
#  <Directory "c:/wamp/www/testing3.com"> 
#   Options +Indexes +Includes +FollowSymLinks +MultiViews 
#   AllowOverride All 
#   Require local 
#  </Directory> 
# </VirtualHost>'; 

preg_match_all(<<what to put here>>, $vHostConfig, $vHostConfigMatches); 

würde ich Ich mag nur die aktiven Konfigurationen ohne ein # am Anfang der Zeile, was bedeutet, dass ich drei Strings haben sollte, die mit <VirtualHost beginnen und mit </VirtualHost> im Array $ vHostConfigMatches enden. Ist das möglich?

+0

während Regex kann dies tatsächlich tun, ist es erwähnenswert, dass eine Art von DOM-Parser wird viel besser und wahrscheinlich effizienter dabei sein. [Anmerkung 1] (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454) :: [Anmerkung 2] (https: // nikic.github.io/2012/06/15/The-true-power-of-regular-expressions.html) – Martin

+0

Ich benutze diesen Code nicht in einem Browser, es ist einige benutzerdefinierte Code für die Verwaltung meiner virtuellen Hosts, es ist so Ich kann benutzerdefinierte Funktionen in meinem Wamp-Menü erstellen – Dan

+0

XHTML ist immer noch DOM strukturiert, unabhängig davon, was Sie mit ihm sehen. – Martin

Antwort

2

Sie könnten diesen regulären Ausdruck verwenden:

preg_match_all('/^\h*<VirtualHost.*?>.*?\R\h*<\/VirtualHost>/sm', 
       $vHostConfig, $vHostConfigMatches); 

Beachten Sie, dass das Array $vHostConfigMatches eine zusätzliche Verschachtelung Ebene haben, so nehmen Sie nur die erste mit reset:

print_r(reset($vHostConfigMatches)); 
+0

Eine elegante Antwort, funktioniert perfekt. Sehr geschätzt :-) – Dan

1

Man könnte es durch die Linie geteilt: $lines = explode(PHP_EOL, $vhostConfig);

Filter alle die kommentierten Zeilen aus: $lines = array_filter($lines, function ($ele) { return substring($ele, 0) != "#"; });

es wieder zusammen: $vhostConfig = implode(PHP_EOL, $lines);

dann einen regulären Ausdruck verwenden, um jede virtuelle zu ziehen Host (Sie können etwas genaueres wollen: preg_match_all("@<VirtualHost [\d\.\*:]+>(.*?)</VirtualHost>@", $vhostConfig, $vhostConfigMatches);

Nicht getestet, aber sollte Ihnen die Idee geben. Dies hat auch den Vorteil einer Kommentarzeile in einem gültigen Virtualhost ignorieren

+0

Liebe den Ansatz, den Sie genommen haben, musste ich Ihren Code etwas bearbeiten '$ Zeilen = Array_filter ($ Zeilen, Funktion ($ Ele) {return substr ($ ele, 0, 1)! =" # ";}) ; 'Leider funktioniert der preg_match_all nicht? – Dan

+0

Dies war die richtige Antwort, um nur die aktiven Konfigurationen zu erfassen, aber das Regex-Muster auf trincots Antwort ist korrekt, um die aktiven Konfigurationen in drei Array-Elemente aufzuteilen – Dan

0

Obwohl die Antwort des @ Trincot funktioniert gut, es nutzt die .*? (faul) quantifier, die die Regex-Engine hochaktiv macht: diese regex101 zeigt, dass es in diesem Beispiel 950 Schritte benötigt.

So denke ich, dass, auch wenn es ein bisschen komplizierter scheint, dieser einfache PHP-Schnipsel würde schneller laufen:

$result = array_reduce(
    explode(PHP_EOL, $str), 
    function($result, $line) { 
    if (trim($line[0]) <> '#') { 
     if (strpos($line, '<VirtualHost') !== false) { 
     $result[] = $line; 
     } else { 
     $result[count($result) - 1] .= $line; 
     } 
    } 
    return $result; 
    }, 
    [] 
); 

Sogleich es lediglich:

  • schaltet die ursprüngliche Zeichenfolge in eine Anordnung von Linien
  • jeden Kommentar Drop
  • auffüllt das benötigte Ergebnis wie erwartet