我试图匹配以下模式并创建一个数组,如下所述:
letter 'c' followed by digitletter 'c' followed by digit dash digitdigit may be followed by an other digit enclosed in square parentheses []模式用逗号分隔。
示例:
c2,c3-5,c6[2],c8[4]-10,c14-21[5]这些数字是指法律条款的段落,如果有破折号,就意味着这是一系列段落。
例如:
c3-5 = paragraphs from 3 to 5使用以下正则表达式,我可以匹配并分离数字:
(\d+(\[\d+\])?-\d+(\[\d+\])?)|(\d+(\[\d+\])?)https://regex101.com/r/iQ2pQ3/1
但是,为了有效地使用这些数字,我试图构建一个具有以下结构的数组,但没有成功:
Array
(
[0] => Array
(
[start] => 2
[end]=>
)
[1] => Array
(
[start] => 3
[end] => 5
)
[2] => Array
(
[start] => 6[2]
[end] =>
)
[3] => Array
(
[start] => 8[4]
[end] => 10
)
[4] => Array
(
[start] => 14
[end] => 21[5]
)
)您可能会看到,单个匹配被添加到带有键[start]的数组中,当有一个破折号(一个范围)时,第一个数字被添加到[start]键中,第二个数字添加到键[end]中。
唯一的方法,我认为我可以找到它,首先explode字符串逗号,然后使用正则表达式对单个爆炸的字符串。即使是思考,也不知道如何像上面的那样构建数组。
有没有一种更好(更紧凑、更优雅)的方法来做到这一点?
发布于 2016-03-31 09:31:57
使用以下基于regex的解决方案(请参阅演示):
$re = '~c(?<start>\d+(?:\[\d+])?)(?:-(?<end>(?&start)?))?~';
$str = "c2,c3-5,c6[2],c8[4]-10,c14-21[5]";
preg_match_all($re, $str, $matches);
$res = array_map(function($ms, $me) {
return array("start" => $ms, "end" => $me);
}, $matches["start"], $matches["end"]);
print_r($res);regex类似于anubhava的,但是我通过一个命名的子例程调用(它实际上是递归、搜索、start子模式)来缩短它:
c(?<start>\d+(?:\[\d+])?)(?:-(?<end>(?&start)?))?参见regex演示,这是它的解释:
c -文字c(?<start>\d+(?:\[\d+])?) -(名为“start”的组)是一个强制性子模式,\d+匹配1+数字,该数字可选地后面跟着1次:,后面跟着[ + named + ](?:-(?<end>(?&start)?))? -1或0(可选的) -序列后面跟着"start“组(值被放置到"end”组中)。发布于 2016-03-31 09:24:50
您也可以将正则表达式修改为捕获空匹配:
c(?P<start>\d+(?:\[\d+\])?)-?(?P<end>\d+(?:\[\d+\])?|)(?=,|$)(?P<end>\d+(?:\[\d+\])?|)确保我们还捕获end组中的空匹配。
https://stackoverflow.com/questions/36328961
复制相似问题