Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 将正则表达式匹配项代表其位置添加到二维数组中_Php_Arrays_Regex - Fatal编程技术网

Php 将正则表达式匹配项代表其位置添加到二维数组中

Php 将正则表达式匹配项代表其位置添加到二维数组中,php,arrays,regex,Php,Arrays,Regex,我正在尝试匹配以下模式并创建一个数组,如下所述: 字母“c”后跟数字 字母“c”后跟数字破折号数字 数字后面可以跟一个用方括号括起来的其他数字[] 模式由逗号分隔 例如: c2,c3-5,c6[2],c8[4]-10,c14-21[5] 这些数字指的是法律条款中的段落,如果有破折号,则表示这是一系列段落 例如: c3-5 = paragraphs from 3 to 5 使用以下正则表达式,我可以匹配和分隔数字: (\d+(\[\d+\])?-\d+(\[\d+\])?)|(\d+(\[

我正在尝试匹配以下模式并创建一个数组,如下所述:

  • 字母“c”后跟数字
  • 字母“c”后跟数字破折号数字
  • 数字后面可以跟一个用方括号括起来的其他数字[]
模式由逗号分隔

例如:

c2,c3-5,c6[2],c8[4]-10,c14-21[5]
这些数字指的是法律条款中的段落,如果有破折号,则表示这是一系列段落

例如:

c3-5 = paragraphs from 3 to 5
使用以下正则表达式,我可以匹配和分隔数字:

(\d+(\[\d+\])?-\d+(\[\d+\])?)|(\d+(\[\d+\])?)

但为了有效地使用这些数字,我正在尝试构建一个具有以下结构的数组,但没有成功:

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]

我认为唯一的方法是首先用逗号分解字符串,然后在单个分解的字符串上使用正则表达式。甚至连想都不知道如何构建如上所述的阵列


有没有更好(更简洁、更优雅)的方法呢?

您可以将正则表达式修改为此,以捕获空匹配:

c(?P<start>\d+(?:\[\d+\])?)-?(?P<end>\d+(?:\[\d+\])?|)(?=,|$)
c(?P\d+(?:\[\d+\]))-?(?P\d+(?:\[\d+\])?)(?=,|$)


(?p\d+(?:\[\d+\])?)
确保在
end
组中捕获空匹配项。

使用以下基于正则表达式的解决方案(请参阅):

请参阅,以下是其说明:

  • c
    -文字
    c
  • (?\d+(?:\[\d+])?)
    -(名为“开始”的组)一个强制子模式,
    \d+
    匹配1个以上的数字,可以选择后跟1个出现的
    ,后跟
    [
    +数字+
    ]
  • (?:-(?(?&start)?)?
    -1或0(可选)序列的
    -
    ,后跟“start”组(值放入“end”组)

太棒了!我不知道团体可以被命名。非常好而且有用的解释。
$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);
c(?<start>\d+(?:\[\d+])?)(?:-(?<end>(?&start)?))?