简体   繁体   English

PHP的preg_match_all多行模式

[英]php preg_match_all of multiple lines pattern

I'm stuck at this question and hope any one out there can help me. 我坚持这个问题,希望在那里的任何人都能帮助我。

I have a config file that contains following lines: 我有一个包含以下行的配置文件:

config system interface
edit "internal1"
    set vdom "root"
    set ip 192.168.1.1 255.255.255.0
    set allowaccess ping https ssh http fgfm capwap
    set type physical
    set snmp-index 1
next
edit "internal2"
    set vdom "root"
    set ip 192.168.20.2 255.255.255.0
    set allowaccess ping https ssh http fgfm capwap
    set type physical
    set snmp-index 2
    Set secondary-IP enable
      config secondaryip
        edit 1
          set ip 192.168.21.2 255.255.255.0
        next
        edit 2
          set ip 192.168.22.2 255.255.255.0
        next
      end
next
edit "internal3"
    set vdom "root"
    set ip 192.168.30.3 255.255.255.0
    set allowaccess ping https ssh http fgfm capwap
    set type physical
    set snmp-index 3
    Set secondary-IP enable
      config secondaryip
        edit 1
          set ip 192.168.31.3 255.255.255.0
        next
      end
next
end
....

And want to Match for interface's Name, vdom, vlanid, ip and secondary-ip(s) with following regex: 并希望使用以下正则表达式匹配接口的名称,vdom,vlanid,ip和secondary-ip:

preg_match_all("/edit .+(\s+config secondaryip\r?\n(\s+edit \d+\r?\n.+\s+next\r?\n){1,}\s+end\r?\n)?.+next\r?\n/s", $configFile, $matched_interfaces);

with the first .+ is everything matched and not the others! 与第一个.+匹配的是所有内容,而不是其他所有!

Thx for any suggestions 感谢任何建议

I love regex 我爱正则表达式

$regex = '/(?<=\vedit ")(\w+)|(?<=vdom ")(\w+)|(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?=\s+set)|(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?=\s+next)/';
print_r(preg_match_all($regex, $configFile, $matched_interfaces));

Output is 输出是

Array
(
[0] => Array
(
[0] => internal1
[1] => root
[2] => 192.168.1.1 255.255.255.0
[3] => internal2
[4] => root
[5] => 192.168.20.2 255.255.255.0
[6] => 192.168.21.2 255.255.255.0
[7] => 192.168.22.2 255.255.255.0
[8] => internal3
[9] => root
[10] => 192.168.30.3 255.255.255.0
[11] => 192.168.31.3 255.255.255.0
)

[1] => Array
(
[0] => internal1
[1] => 
[2] => 
[3] => internal2
[4] => 
[5] => 
[6] => 
[7] => 
[8] => internal3
[9] => 
[10] => 
[11] => 
)

[2] => Array
(
[0] => 
[1] => root
[2] => 
[3] => 
[4] => root
[5] => 
[6] => 
[7] => 
[8] => 
[9] => root
[10] => 
[11] => 
)

[3] => Array
(
[0] => 
[1] => 
[2] => 192.168.1.1 255.255.255.0
[3] => 
[4] => 
[5] => 192.168.20.2 255.255.255.0
[6] => 
[7] => 
[8] => 
[9] => 
[10] => 192.168.30.3 255.255.255.0
[11] => 
)

[4] => Array
(
[0] => 
[1] => 
[2] => 
[3] => 
[4] => 
[5] => 
[6] => 192.168.21.2 255.255.255.0
[7] => 192.168.22.2 255.255.255.0
[8] => 
[9] => 
[10] => 
[11] => 192.168.31.3 255.255.255.0
)

)

Edit to answer follow up 编辑以回答跟进

(?<=\\vedit ") This is a positive look behind construct, and has to be in parenthesis. This bit ?<= specifies its a positive look behind \\v matches vertical whitespace and edit " literally matches edit ". This is followed by (\\w+) which means match word characters as many times as you can, putting it in parenthesis creates a capture group so you can reference the match later. The positive look behind means that the (\\w+) pattern will only match if the look behind sequence immediately before it also matches (?<=\\vedit ")这是一个正向构造,必须放在括号中。 ?<=指定它的正向\\v匹配垂直空格并edit "字面匹配edit”。 (\\w+)表示要尽可能多地匹配单词字符,将其放在括号中会创建一个捕获组,以便以后可以引用该匹配项。后面的正向表示(\\w+)模式仅在在还匹配之前先查看序列

You can add group names to your capture groups to have them returned as a named array 您可以将组名称添加到捕获组中,以使它们作为命名数组返回

$regex = '/(?<=edit ")(?<name>\w+)\K|(?<=vdom ")(?<vdom>\w+)|(?<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?=\s+set)|(?<secondary>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?=\s+next)\K/';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM