[英]Regex repeated capturing group in PHP
我正在嘗試從帶有路由的一個文件中獲取信息,因此對於這項工作,我選擇了正則表達式,但是我對重復的信息有疑問,為了做一個更好的問題,我將放置我擁有的東西以及我想要擁有的東西:
所以我有一個文件:
Codes: C - Connected, S - Static, R - RIP, B - BGP,
O - OSPF IntraArea (IA - InterArea, E - External, N - NSSA)
A - Aggregate, K - Kernel Remnant, H - Hidden, P - Suppressed,
U - Unreachable, i - Inactive
O E 0.0.0.0/0 via 10.140, bond1.30, cost 1:10, age 5
via 10.141, bond1.31
via 10.142, bond1.32
O E 10.112/23 via 10.140, bond1.30, cost 46:1, age 2511
O E 10.112/23 via 10.140, bond1.30, cost 46:1, age 2511
O IA 10.138/29 via 10.140, bond1.30, cost 46, age 1029440
C 10.141/29 is directly connected, bond2.35
C 10.141/29 is directly connected, bond2.35
我做了這個正則表達式:
(S|R|B|O|A|K|H|P|U|i) +(IA|E|N|) +([0-9.]+)\/([0-9]+) +via +([0-9.]+), +([a-zA-Z0-9.]+|), +cost +([0-9]+:|)([0-9]+), +age +[0-9]+ +\n(( +via +([0-9.]+), +([a-zA-Z0-9.]+|) +\n)+|)
我的問題是結尾部分(( +via +([0-9.]+), +([a-zA-Z0-9.]+|) +\\n)+|)
因為此正則表達式讓我知道了
array[0]=>' via 10.141, bond1.31
via 10.142, bond1.32';
array[1]=>'10.142';
array[2]=>'bond1.32';
但是我想得到
array[0]=>'10.141';
array[1]=>'bond1.31';
array[3]=>'10.142';
array[4]=>'bond1.32';
我在有關正則表達式的頁面中測試了正則表達式,其中之一告訴我:
注意:重復捕獲組將僅捕獲最后一次迭代。 將捕獲組放在重復的組周圍以捕獲所有迭代,或者如果您對數據不感興趣,則使用非捕獲組
但是我真的不知道這是什么意思,以及如何解決它。
注意:這是為了獲得文件關於與show ip route
思科的show ip route
更新1
我將正則表達式更改為
(S|R|B|O|A|K|H|P|U|i) +(IA|E|N|) +([0-9.]+)\/([0-9]+) +via +([0-9.]+), +([a-zA-Z0-9.]+|), +cost +([0-9]+:|)([0-9]+), +age +[0-9]+ +\n(?: +via +([0-9.]+), +([a-zA-Z0-9.]+|) +\n)*
這樣我就沒有了
array[0]=>' via 10.141, bond1.31
via 10.142, bond1.32';
但是我沒有重復的部分
恐怕您將需要使用另一個正則表達式來獲取重復的子模式匹配項。 因此,您可以執行以下操作:
preg_match_all("/(?:S|R|B|O|A|K|H|P|U|i) +(?:IA|E|N|) +[0-9.]+\/[0-9]+ +via +([0-9.]+), +([a-zA-Z0-9.]+|), +cost +(?:[0-9]+:|)[0-9]+, +age +[0-9]+ +\n((?: +via +[0-9.]+, +(?:[a-zA-Z0-9.]+|) +\n)*)/",$s,$matches,PREG_SET_ORDER);
foreach($matches as $id=>$match)
{
unset($matches[$id][0]);
if(isset($match[3])) {
preg_match_all("/ +via +([0-9.]+), +([a-zA-Z0-9.]+|) +\n/",$match[3],$subpatternMatches,PREG_SET_ORDER);
unset($matches[$id][3]);
foreach($subpatternMatches as $spmid=>$spm) {
unset($subpatternMatches[$spmid][0]);
$matches[$id] = array_merge($matches[$id],$subpatternMatches[$spmid]);
}
}
}
它將為您的示例文件獲取以下數據:
array(4) {
[0]=>
array(6) {
[0]=>
string(6) "10.140"
[1]=>
string(8) "bond1.30"
[2]=>
string(6) "10.141"
[3]=>
string(8) "bond1.31"
[4]=>
string(6) "10.142"
[5]=>
string(8) "bond1.32"
}
[1]=>
array(2) {
[1]=>
string(6) "10.140"
[2]=>
string(8) "bond1.30"
}
[2]=>
array(2) {
[1]=>
string(6) "10.140"
[2]=>
string(8) "bond1.30"
}
[3]=>
array(2) {
[1]=>
string(6) "10.140"
[2]=>
string(8) "bond1.30"
}
}
好的,我已經像這樣更改了您的正則表達式:
$txt = "Codes: C - Connected, S - Static, R - RIP, B - BGP,
O - OSPF IntraArea (IA - InterArea, E - External, N - NSSA)
A - Aggregate, K - Kernel Remnant, H - Hidden, P - Suppressed,
U - Unreachable, i - Inactive
O E 0.0.0.0/0 via 10.140, bond1.30, cost 1:10, age 5
via 10.141, bond1.31
via 10.142, bond1.32
O E 10.112/23 via 10.140, bond1.30, cost 46:1, age 2511
O E 10.112/23 via 10.140, bond1.30, cost 46:1, age 2511
O IA 10.138/29 via 10.140, bond1.30, cost 46, age 1029440
C 10.141/29 is directly connected, bond2.35
C 10.141/29 is directly connected, bond2.35
";
$regexp = '#(.) +([A-Z]{1,2}) +([\d.]+/\d+) +via ([\d.]+), ([a-zA-Z0-9.]+), cost [\d:]+, age \d+ +(?:\n +via ([\d.]+), ([a-zA-Z0-9.]+))*#m';
$matches = [];
preg_match_all($regexp, $txt, $matches, PREG_SET_ORDER);
var_dump($matches);
輸出為:
array(4) {
[0] =>
array(8) {
[0] =>
string(125) "O E 0.0.0.0/0 via 10.140, bond1.30, cost 1:10, age 5
via 10.141, bond1.31"
[1] =>
string(1) "O"
[2] =>
string(1) "E"
[3] =>
string(9) "0.0.0.0/0"
[4] =>
string(6) "10.140"
[5] =>
string(8) "bond1.30"
[6] =>
string(6) "10.141"
[7] =>
string(8) "bond1.31"
}
[1] =>
array(6) {
[0] =>
string(69) "O E 10.112/23 via 10.140, bond1.30, cost 46:1, age 2511 "
[1] =>
string(1) "O"
[2] =>
string(1) "E"
[3] =>
string(9) "10.112/23"
[4] =>
string(6) "10.140"
[5] =>
string(8) "bond1.30"
}
[2] =>
array(6) {
[0] =>
string(69) "O E 10.112/23 via 10.140, bond1.30, cost 46:1, age 2511 "
[1] =>
string(1) "O"
[2] =>
string(1) "E"
[3] =>
string(9) "10.112/23"
[4] =>
string(6) "10.140"
[5] =>
string(8) "bond1.30"
}
[3] =>
array(6) {
[0] =>
string(70) "O IA 10.138/29 via 10.140, bond1.30, cost 46, age 1029440 "
[1] =>
string(1) "O"
[2] =>
string(2) "IA"
[3] =>
string(9) "10.138/29"
[4] =>
string(6) "10.140"
[5] =>
string(8) "bond1.30"
}
}
它不起作用,因為缺少第三個通孔
新版本,逐行:
$txt = "Codes: C - Connected, S - Static, R - RIP, B - BGP,
O - OSPF IntraArea (IA - InterArea, E - External, N - NSSA)
A - Aggregate, K - Kernel Remnant, H - Hidden, P - Suppressed,
U - Unreachable, i - Inactive
O E 0.0.0.0/0 via 10.140, bond1.30, cost 1:10, age 5
via 10.141, bond1.31
via 10.142, bond1.32
O E 10.112/23 via 10.140, bond1.30, cost 46:1, age 2511
O E 10.112/23 via 10.140, bond1.30, cost 46:1, age 2511
O IA 10.138/29 via 10.140, bond1.30, cost 46, age 1029440
C 10.141/29 is directly connected, bond2.35
C 10.141/29 is directly connected, bond2.35
";
$grouped = [];
$i = 0;
foreach (explode("\n", $txt) as $line) {
$matches = [];
if (preg_match('#^(.) +([A-Z]{1,2}) +([\d.]+/\d+) +via ([\d.]+), ([a-zA-Z0-9.]+)#', $line, $matches)) {
array_shift($matches);
$grouped[++$i] = $matches;
} else if(preg_match('#^ +via ([\d.]+), ([a-zA-Z0-9.]+)#', $line, $matches)){
array_push($grouped[$i], $matches[1], $matches[2]);
}
}
var_dump($grouped);
現在它正在工作:
array(4) {
[1] =>
array(9) {
[0] =>
string(1) "O"
[1] =>
string(1) "E"
[2] =>
string(9) "0.0.0.0/0"
[3] =>
string(6) "10.140"
[4] =>
string(8) "bond1.30"
[5] =>
string(6) "10.141"
[6] =>
string(8) "bond1.31"
[7] =>
string(6) "10.142"
[8] =>
string(8) "bond1.32"
}
[2] =>
array(5) {
[0] =>
string(1) "O"
[1] =>
string(1) "E"
[2] =>
string(9) "10.112/23"
[3] =>
string(6) "10.140"
[4] =>
string(8) "bond1.30"
}
[3] =>
array(5) {
[0] =>
string(1) "O"
[1] =>
string(1) "E"
[2] =>
string(9) "10.112/23"
[3] =>
string(6) "10.140"
[4] =>
string(8) "bond1.30"
}
[4] =>
array(5) {
[0] =>
string(1) "O"
[1] =>
string(2) "IA"
[2] =>
string(9) "10.138/29"
[3] =>
string(6) "10.140"
[4] =>
string(8) "bond1.30"
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.