[英]Php Regex: how to match repeated patterns
給定以下文字
bond0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
eth0: 11329920252 12554462 0 0 0 0 0 3561 13072970332 12899522 0 0 0 0 0 0
我需要捕獲列值。 我對這些台詞有一些想法:
Regex: `(\w+):(?:\s+(\d+))+`
Php: `preg_match_all('/(\w+):(?:\s+(\d+))+/sim', $data, $regs)
但不幸的是,它僅捕獲第一列。
Array
(
[0] => Array
(
[0] => dummy0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[1] => bond0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[2] => eth0: 11329920252 12554462 0 0 0 0 0 3561 13072970332 12899522 0 0 0 0 0 0
[3] => ip6tnl0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[4] => lo: 51675995 100695 0 0 0 0 0 0 51675995 100695 0 0 0 0 0 0
[5] => sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[6] => tunl0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
)
[1] => Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 0
[5] => 0
[6] => 0
)
)
有什么建議嗎? 謝謝`
==== 編輯 ====只是要清楚:我知道我可以preg_match
搜索\\d+
值或將整個字符串分成preg_match
行並在每一行上運行,但是我對正則表達式解決方案感興趣,將第一列作為結果數組的第一成員(准確地忘記將捕獲括號放在問題的初稿中),並在緊隨數據的列之后,將每一行放入其專用數組中...
為什么要全部使用preg_match
或preg_match_all
?
$results = array();
foreach (preg_split("/\r\n|\r|\n/", $data) as $line)
{
list($key, $values) = explode(":", $line);
$results[$key] = preg_split("/\s/", trim($values));
}
這應該只要沒有超過一個工作:
在每一行。 在我看來,這也是最短,最快的編寫方法。
干得好:
$data = explode("\n", $data);
$out = array();
foreach ($data as $d) {
preg_match_all('/\s(\d+)/', $d, $matches);
將$matches[0]
放入$matches[0]
數組。 然后,您要將其添加到行數組中:
$out[] = $matches[0];
}
現在,您將看到行和列的鋸齒狀數組。 因此,要引用第二行的第四列,可以轉到$out[1][3]
。
您可以這樣做:
$subject = <<<LOD
dummy0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
bond0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
eth0: 11329920252 12554462 0 0 0 0 0 3561 13072970332 12899522 0 0 0 0 0 0
ip6tnl0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
lo: 51675995 100695 0 0 0 0 0 0 51675995 100695 0 0 0 0 0 0
sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
tunl0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
LOD;
$pattern = '~^(?<item>\w++)\s*:|\G\s*(?<value>\d++)~m';
preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER);
$i=-1;
foreach($matches as $match) {
if (isset($match['value']))
$result[$i]['values'][] = $match['value'];
else {
$i++;
$result[$i]['item'] = $match['item']; }
}
print_r($result);
您將獲得在EDIT中描述的格式。
圖案細節:
~ # pattern delimiter
^ # anchor for the line start (in multiline mode)
(?<item>\w++) # named capture "item"
\s*:
| # OR
\G # force the match to be contiguous from precedent
\s* #
(?<value>\d++) # named capture "value"
~m # pattern delimiter, m modifier for multiline mode
我知道您正在尋找preg_match
解決方案,但是以防萬一您找不到任何有用的答案
<?php
$val = "bond0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
eth0: 11329920252 12554462 0 0 0 0 0 3561 13072970332 12899522 0 0 0 0 0 0";
$arr1 = explode("\n",$val);
foreach ($arr1 as $value) {
$exp = explode(":",$value);
$ex = preg_replace('/\s+/', ' ',trim($exp[1]));
$arr[$exp[0]] = explode(" ",$ex);
}
var_dump($arr);
?>
結果:
array (size=2)
'bond0' =>
array (size=17)
0 => string '' (length=0)
1 => string '0' (length=1)
2 => string '0' (length=1)
3 => string '0' (length=1)
4 => string '0' (length=1)
5 => string '0' (length=1)
6 => string '0' (length=1)
7 => string '0' (length=1)
8 => string '0' (length=1)
9 => string '0' (length=1)
10 => string '0' (length=1)
11 => string '0' (length=1)
12 => string '0' (length=1)
13 => string '0' (length=1)
14 => string '0' (length=1)
15 => string '0' (length=1)
16 => string '0' (length=1)
'eth0' =>
array (size=17)
0 => string '' (length=0)
1 => string '11329920252' (length=11)
2 => string '12554462' (length=8)
3 => string '0' (length=1)
4 => string '0' (length=1)
5 => string '0' (length=1)
6 => string '0' (length=1)
7 => string '0' (length=1)
8 => string '3561' (length=4)
9 => string '13072970332' (length=11)
10 => string '12899522' (length=8)
11 => string '0' (length=1)
12 => string '0' (length=1)
13 => string '0' (length=1)
14 => string '0' (length=1)
15 => string '0' (length=1)
16 => string '0' (length=1)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.