php - PHP 中的正则表达式命名捕获组

标签 php regex

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

$list = '10,9,8,7,6,5,4,3,2,1';

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

$matches = array();
if (preg_match($regex,$list,$matches)==1) {
    print_r($matches);
}

哪些输出:

Array ( [0] => 10,9,8,7,6,5,4,3,2,1 ) 

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

编辑

为了更清楚地说明,我想最终使用递归,所以 explode 并不理想:

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

最佳答案

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

字符串示例:1abcde2

如果我使用此模式:/^(?<num>\d).....(?&num)$/1num组中捕获,(?&num)不捕获任何内容,它只是 \d 的别名.
/^(?<num>\d).....\d$/产生完全相同的结果。

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

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

  1. 您想要检查字符串的格式。
  2. 您想要提取未知数量的项目。

这样做仅在特定情况下才有可能,但一般情况下是不可能的。

例如,使用如下平面列表:$list = '10,9,8,7,6,5,4,3,2,1';如果没有嵌套元素,您可以使用类似 preg_match_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 '<°)))))))>';
}

现在,如果您有一个像 $list = '10,9,(8,(7,6),5),4,(3,2),1'; 这样的嵌套列表例如,您想要检查格式并生成如下树结构:

[ 10, 9, [ 8, [ 7, 6 ], 5 ], 4 , [ 3, 2 ], 1 ]

单次通过是无法做到这一点的。您需要一种模式来检查整个字符串格式,并需要另一种模式来提取元素(以及一个递归函数来使用它)。

<<<FORGET_THIS_IMMEDIATELY

顺便说一句,你可以用 eval 来做到这一点和strtr ,但这是一种非常肮脏和危险的方式:

eval('$result=[' . strtr($list, '()', '[]') . '];');

FORGET_THIS_IMMEDIATELY;

关于php - PHP 中的正则表达式命名捕获组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31677485/

相关文章:

php - 将数组变量导出到 csv 时,如何删除带有 2 个或多个变量的双引号,这些变量形成一个字符串?

php - 强制浏览器重新读取ajax结果

php - 解析JSON并加载到MYSQL的性能

javascript - regex101 条件语句总是 else

python - 无法让 Python 正则表达式反向引用发挥作用

python - 在 Django 中使用 Python 正则表达式

php - while循环mysql/PHP超过执行时间

regex - 使用 sed,在不同长度的单词周围加上引号

python - 如何使用正则表达式中的变量在 python 中增加整个单词匹配

php - SQL插入后获取最后一个ID