Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/262.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_Regex - Fatal编程技术网

正则表达式在PHP中命名为捕获组

正则表达式在PHP中命名为捕获组,php,regex,Php,Regex,我有以下正则表达式来捕获一个数字列表(最终会比这更复杂): 如何在$matches数组中捕获列表中的单个数字?我似乎无法做到这一点,尽管在数字(\d+)周围放置了一个捕获组 编辑 为了更清楚,我希望最终使用递归,因此explode并不理想: $match = <<<REGEX /(?x) (?(DEFINE) (?<number> (\d+) ) (?<member> (?&number)|(?&

我有以下正则表达式来捕获一个数字列表(最终会比这更复杂):

如何在$matches数组中捕获列表中的单个数字?我似乎无法做到这一点,尽管在数字(\d+)周围放置了一个捕获组

编辑

为了更清楚,我希望最终使用递归,因此explode并不理想:

$match = 
<<<REGEX
    /(?x)
    (?(DEFINE)
        (?<number> (\d+) )
        (?<member> (?&number)|(?&list) )
        (?<list> \( ((?&number)|(?&member))(,(?&member))* \) ) 
    )
    ^(?&list)/
REGEX;
$match=

若要获取逗号分隔的数字数组,请分解:

$numbers = explode(',', $matches[0]); //first parameter is your delimiter what the string will be split up by. And the second parameter is the initial string
print_r($numbers);
输出:

Array(
    [0] => 10,
    [1] => 9,
    [2] => 8,

etc

对于这个简单的列表,这就足够了(如果必须使用正则表达式):

(?(DEFINE)…)
部分的目的只是定义命名子模式,您可以稍后在DEFINE部分本身或主模式中使用。因为这些子模式没有在主模式中定义,所以它们不会捕获任何内容,而引用
(?&number)
只是子模式
\d+
的一种别名,也不会捕获任何内容

字符串示例:
1abcde2

如果我使用此模式:
/^(?\d)…(?&num)$/
组num中只捕获
1
(?&num)
不捕获任何内容,它只是
\d

/^(?\d)…\d$/
的别名,产生完全相同的结果

还有一点需要澄清。使用PCRE(PHP正则表达式引擎),捕获组(无论是否命名)只能存储一个值,即使您重复它

你的方法的主要问题是你试图同时做两件事:

  • 您想检查字符串的格式
  • 您想提取未知数量的项目
  • 这样做只有在特定情况下才可能,但在一般情况下是不可能的

    例如,使用平面列表,如:
    $list='10,9,8,7,6,5,4,3,2,1'在没有嵌套元素的情况下,可以使用类似于
    preg\u match\u all
    的函数以这种方式多次重用同一模式:

    if (preg_match_all('~\G(\d+)(,|$)~', $list, $matches) && !end($matches[2])) {
        // \G ensures that results are contiguous
        // you have all the items in $matches[1] 
        // if the last item of $matches[2] is empty, this means
        // that the end of the string is reached and the string
        // format is correct
        echo '<°)))))))>';
    }
    
    一次传球是不行的。您需要一个模式来检查整个字符串格式,另一个模式来提取元素(以及使用它的递归函数)


    谢谢你,至少我知道这是不可能的。环顾四周,似乎只有.NET正则表达式捕获了所有重复组。不过,递归匹配还是相当强大的@GuillermoPhillips:新的python正则表达式模块也可以这样做。实际上,您可以通过添加另一组括号来捕获第二个数字,如/^(?\d)…((?&num))$/,但是,第二个组将被捕获为\2,即未命名。@RudigerW://显然,但这只是一个例子来说明反向引用不是捕获这一事实。
    
    Array(
        [0] => 10,
        [1] => 9,
        [2] => 8,
    
    $string = '10,9,8,7,6,5,4,3,2,1';
    $pattern = '/([\d]+),?/';
    
    preg_match_all($pattern, $string, $matches);
    
    print_r($matches[1]);
    
    if (preg_match_all('~\G(\d+)(,|$)~', $list, $matches) && !end($matches[2])) {
        // \G ensures that results are contiguous
        // you have all the items in $matches[1] 
        // if the last item of $matches[2] is empty, this means
        // that the end of the string is reached and the string
        // format is correct
        echo '<°)))))))>';
    }
    
    [ 10, 9, [ 8, [ 7, 6 ], 5 ], 4 , [ 3, 2 ], 1 ]
    
    eval('$result=[' . strtr($list, '()', '[]') . '];');