2017-10-05 105 views
0

我被困在這個問題上,希望有人能幫助我。php preg_match_all多行模式

我有一個包含如下的配置文件:

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 
.... 

而想要匹配接口的名稱,VDOM,VLANID,ip和二次-IP(S)具有以下的正則表達式:

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

與第一個.+是一切匹配,而不是其他人!

THX的任何建議

+0

讓它不那麼貪婪,就是說,這個文件str ucture不適合一次性提取。隨着可能的任意排序和嵌套,一些標記和狀態機將是明智的。 – mario

回答

0

我愛正則表達式

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

輸出是

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 
) 

) 

編輯回答跟進

(?<=\vedit ")這背後是結構正面看,並有t o在括號內。這位?<=指定了其正面的背後\v匹配垂直空白和edit "字面上匹配編輯「。其次是(\w+)這意味着匹配單詞字符儘可能多次,將它放在括號中創建一個捕獲組,以便您可以引用比賽後,正看背後意味着,(\w+)模式將只匹配,如果後面序列的外觀之前它也符合

可以組名稱添加到您的捕捉組,讓他們返回一個命名的數組

$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/'; 
+0

許多thx miknik!你能給我一個關於「<?<= \ v」的簡短解釋嗎?我怎樣才能讓匹配數組與相應的鍵相關? – matrix154

+0

更新了我的答案 – miknik