[英]Convert the matches of a regex into a multidimensional array
下面的代码正确匹配:
letter 'c' followed by digit
letter 'c' followed by digit dash digit
digit may be followed by an other digit enclosed in square parentheses []
并按预期方式创建一个数组:
Array
(
[0] => Array
(
[start] => 4
[end]=> 8
)
[1] => Array
(
[start] => 2
[end]=>
)
[2] => Array
(
[start] => 3
[end] => 5
)
[3] => Array
(
[start] => 6[2]
[end] =>
)
[4] => Array
(
[start] => 8[4]
[end] => 10
)
[5] => Array
(
[start] => 14
[end] => 21[5]
)
)
码:
$str = "a2c4-8|a6c2,c3-5,c6[2],c8[4]-10,c14-21[5]";
$re = "~c(?<start>\d+(?:\[\d+])?)(?:-(?<end>(?&start)?))?~";
$myarray = explode("|",$str);
foreach ($myarray as $my) {
preg_match_all($re, $my, $matches);
$res = array_map(function($ms, $me) {
return array("start" => $ms, "end" => $me);
}, $matches["start"], $matches["end"]);
}
echo "<pre>";
print_r($res);
echo "</pre>";
现在,我想在a
之后添加另一个具有数字值的key
。 因此,例如,鉴于上述$str
$str = "a2c4-8|a6c2,c3-5,c6[2],c8[4]-10,c14-21[5]".
a
值为: 2
和6
,预期结果数组如下。 注意,每个匹配的c
重复6
。
Array
(
[0] => Array
(
[a] => 2
[start] => 4
[end]=> 8
)
[1] => Array
(
[a] => 6
[start] => 2
[end]=>
)
[2] => Array
(
[a] => 6
[start] => 3
[end] => 5
)
[3] => Array
(
[a] => 6
[start] => 6[2]
[end] =>
)
[4] => Array
(
[a] => 6
[start] => 8[4]
[end] => 10
)
[5] => Array
(
[a] => 6
[start] => 14
[end] => 21[5]
)
)
您可以这样做:
$str = "a2c4-8|a6c2,c3-5,c6[2],c8[4]-10,c14-21[5]";
$re = '~(?:a(?<a>\d+))?c(?<start>\d+(?:\[\d+])?)(?:-(?<end>\g<start>))?~';
if (preg_match_all($re, $str, $matches, PREG_SET_ORDER) ) {
$a = ''; // current value for "a" -----,
$result = array_map(function ($i) use (&$a) {
if (!empty($i['a'])) $a = $i['a'];
else $i['a'] = $a;
if (!isset($i['end'])) $i['end'] = '';
foreach ($i as $k=>$v) {
if (is_numeric($k)) unset($i[$k]);
}
return $i;
}, $matches);
}
print_r($result);
但是,如果您已经确切地知道字符串格式是什么,并且不需要验证它,则可能会有更聪明(更快)的方法来获得相同的结果。
例如,对sscanf
使用explode
和格式化的字符串:
$str = "a2c4-8|a6c2,c3-5,c6[2],c8[4]-10,c14-21[5]";
$parts = explode('|', $str);
$result = [];
$keys = ['a', 'start', 'end'];
foreach($parts as $part) {
foreach(explode(',', $part) as $k=>$v) {
if ($k)
list($start, $end) = sscanf($v, 'c%[^-]-%[^,]');
else
list($a, $start, $end) = sscanf($v, 'a%dc%[^-]-%[^,]');
$result[] = array_combine($keys, [$a, $start, $end]);
}
}
print_r($result);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.