preg_match_all для получения списка виртуальных хостов из файла httpd-vhosts.conf xampp с помощью php preg_match_all

#php #regex #xampp

Вопрос:

Это то, что я пробовал, также я не хочу, чтобы хосты и объяснения, которые комментируются #/ ##

 $str = '# Virtual Hosts
#
# Required modules: mod_log_config

# If you want to maintain multiple domains/hostnames on your
# machine you can setup VirtualHost containers for them. Most configurations
# use only name-based virtual hosts so the server doesn't need to worry about
# IP addresses. This is indicated by the asterisks in the directives below.
#
# Please see the documentation at 
# <URL:http://httpd.apache.org/docs/2.4/vhosts/>
# for further details before you try to setup virtual hosts.
#
# You may use the command line option '-S' to verify your virtual host
# configuration.

#
# Use name-based virtual hosting.
#
##NameVirtualHost *:80
#
# VirtualHost example:
# Almost any Apache directive may go into a VirtualHost container.
# The first VirtualHost section is used for all requests that do not
# match a ##ServerName or ##ServerAlias in any <VirtualHost> block.
#
##<VirtualHost *:80>
    ##ServerAdmin webmaster@dummy-host.example.com
    ##DocumentRoot "D:/xampp/htdocs/dummy-host.example.com"
    ##ServerName dummy-host.example.com
    ##ServerAlias www.dummy-host.example.com
    ##ErrorLog "logs/dummy-host.example.com-error.log"
    ##CustomLog "logs/dummy-host.example.com-access.log" common
##</VirtualHost>

##<VirtualHost *:80>
    ##ServerAdmin webmaster@dummy-host2.example.com
    ##DocumentRoot "D:/xampp/htdocs/dummy-host2.example.com"
    ##ServerName dummy-host2.example.com
    ##ErrorLog "logs/dummy-host2.example.com-error.log"
    ##CustomLog "logs/dummy-host2.example.com-access.log" common
##</VirtualHost>



##<VirtualHost *:8080>
    ##ServerName CI1
    ##DocumentRoot D:xampphtdocscodeigniter_1public
##</VirtualHost>

<VirtualHost *:8080>
    ServerName CI2
    DocumentRoot D:xampphtdocscodeigniter_2public
</VirtualHost>

<VirtualHost *:8080>
    ServerName CI3
    DocumentRoot D:xampphtdocscodeigniter_3public
</VirtualHost>';
 

Образец 1

 $pattern1 = "#<s*?$tagnameb[^>]*>(.*?)</$tagnameb[^>]*>#s";
preg_match_all($pattern1, $str, $match);
 

Образец 2

 $pattern2 = "/^(?<!#).*<$tagname.*>(. ?)</tagname>/mis";
preg_match_all($pattern2, $str, $matches);
 

Функция

 function everything_in_tags($str, $tagname)
{
    $pattern1 = "#<s*?$tagnameb[^>]*>(.*?)</$tagnameb[^>]*>#s";
    preg_match_all($pattern1, $str, $match);
    
    $pattern2 = "/^(?<!#).*<$tagname.*>(. ?)</$tagname>/s";
    preg_match_all($pattern2, $str, $matches);
    
    echo '<pre>',print_r($match[1]),'</pre>';
    
    echo '<pre>',print_r($matches[1]),'</pre>';
}

everything_in_tags($str, $tagname);
 

Вывод для шаблона 1

 Array
(
    [0] =>  block.
#
##
    ##ServerAdmin webmaster@dummy-host.example.com
    ##DocumentRoot "D:/xampp/htdocs/dummy-host.example.com"
    ##ServerName dummy-host.example.com
    ##ServerAlias www.dummy-host.example.com
    ##ErrorLog "logs/dummy-host.example.com-error.log"
    ##CustomLog "logs/dummy-host.example.com-access.log" common
##
    [1] => 
    ##ServerAdmin webmaster@dummy-host2.example.com
    ##DocumentRoot "D:/xampp/htdocs/dummy-host2.example.com"
    ##ServerName dummy-host2.example.com
    ##ErrorLog "logs/dummy-host2.example.com-error.log"
    ##CustomLog "logs/dummy-host2.example.com-access.log" common
##
    [2] => 
    ##ServerName CI1
    ##DocumentRoot D:xampphtdocscodeigniter_1public
##
    [3] => 
    ServerName CI2
    DocumentRoot D:xampphtdocscodeigniter_2public

    [4] => 
    ServerName CI3
    DocumentRoot D:xampphtdocscodeigniter_3public

)
 

Вывод для шаблона 2

 Array
(
    [0] => 
    ServerName CI3
    DocumentRoot D:xampphtdocscodeigniter_3public

)
 

Желаемый Результат

 Array
(
    [0] => array(
        [ServerName] : CI2
        [DocumentRoot] : D:xampphtdocscodeigniter_2public
        ),
    [1] => array(
        [ServerName] : CI3
        [DocumentRoot] : D:xampphtdocscodeigniter_3public
        );
)
 

Любая помощь была бы признательна, потому что я новичок в регулярных выражениях….. Также мне не нужны некоторые строки, которые комментируются с помощью#/##, заранее спасибо..

Ответ №1:

Использовать в качестве регулярного выражения:

 '~^s*<VirtualHosts [^>]*>s*ServerNames (?P<ServerName>S )s*DocumentRoots (?P<DocumentRoot>S )s*</VirtualHost>~m'
 

Тогда то, что вам нужно, будет в группах захвата 1/ «Имя_сервера» и 2/ «Корневой каталог документов».

Объяснение:

  1. ^ — Сопоставьте начало строки с m установленным флагом.
  2. s* — Сопоставьте 0 или более символов пробела.
  3. <VirtualHost — Совпадение ‘
  4. s — Сопоставьте 1 или более пробелов.
  5. [^>]* Сопоставьте 0 или более символов, которые не являются’>’.
  6. > — Совпадение «>».
  7. s* — Сопоставьте 0 или более символов пробела.
  8. ServerName — Сопоставьте «Имя сервера».
  9. s — Сопоставьте 1 или более пробелов,
  10. (?P<ServerName>S ) — Сопоставьте 1 или более символов без пробелов в качестве группы захвата «Имя сервера».
  11. s* — Сопоставьте 0 или более символов пробела.
  12. DocumentRoot — Сопоставьте «Корень документа».
  13. s — Сопоставьте 1 или более пробелов,
  14. (?P<DocumentRoot>S ) — Сопоставьте 1 или более символов без пробелов в качестве группы захвата «Корень документа».
  15. s* — Сопоставьте 0 или более символов пробела.
  16. </VirtualHost> — Сопоставьте «</VirtualHost>».

Смотрите демонстрацию регулярных выражений

Код:

 $regex = '^s*<VirtualHosts [^>]*>s*ServerNames (?P<ServerName>S )s*DocumentRoots (?P<DocumentRoot>S )s*</VirtualHost>~m';
preg_match_all($regex, $str, $matches, PREG_SET_ORDER);
print_r($matches);
 

С принтами:

 Array
(
    [0] => Array
        (
            [0] =>
<VirtualHost *:8080>
    ServerName CI2
    DocumentRoot D:xampphtdocscodeigniter_2public
</VirtualHost>
            [ServerName] => CI2
            [1] => CI2
            [DocumentRoot] => D:xampphtdocscodeigniter_2public
            [2] => D:xampphtdocscodeigniter_2public
        )

    [1] => Array
        (
            [0] =>
<VirtualHost *:8080>
    ServerName CI3
    DocumentRoot D:xampphtdocscodeigniter_3public
</VirtualHost>
            [ServerName] => CI3
            [1] => CI3
            [DocumentRoot] => D:xampphtdocscodeigniter_3public
            [2] => D:xampphtdocscodeigniter_3public
        )

)
 

Обновить

Приведенное выше регулярное выражение предполагает, что спецификация DocumentRoot не содержит встроенных пробелов, что может быть не всегда так. В нем также было постороннее, ненужное s* , которое я удалил. Следующее регулярное выражение, я полагаю, является улучшением. Он заменяет S , который соответствует 1 или более символам без пробелов . ? , на, который не будет жадно соответствовать 1 или более любому символу (за исключением символа новой строки). Поскольку за ним следует s*</VirtualHost> , будучи не жадным, он перестанет соответствовать, как только обнаружит, что » </VirtualHost> необязательно предшествует любому пробелу.

Таким образом, новое регулярное выражение будет (использоваться с m флагом):

 ^s*<VirtualHosts [^>]*>s*ServerNames (?P<ServerName>S )s*DocumentRoots (?P<DocumentRoot>. ?)s*</VirtualHost>
 

Смотрите новую демонстрацию регулярных выражений

 $regex = '^s*<VirtualHosts [^>]*>s*ServerNames (?P<ServerName>S )s*DocumentRoots (?P<DocumentRoot>. ?)s*</VirtualHost>~m';
preg_match_all($regex, $str, $matches, PREG_SET_ORDER);
print_r($matches);
 

Комментарии:

1. большое вам спасибо за помощь, вы действительно сэкономили мое время, я потратил более 2 дней на поиск этого в Google, но никакие ответы мне не помогли. еще раз мне очень жаль, что я не могу проголосовать, так как у меня нет репутации 15. но бесконечный голос с моей стороны. Спасибо