正则表达式中的动态捕获组


Dynamic capture groups in regular expressions

给定以下PHP代码:

<?php
$str = '/foo/bar/baz';
preg_match('#^(/[^/]+?)*$#', $str, $matches);
var_dump($matches);

。我得到以下输出:

array (size=2)
  0 => string '/foo/bar/baz' (length=12)
  1 => string '/baz' (length=4)

。但我不明白为什么。 我希望每场比赛(/[^/]+?)都被捕获到自己的组中并卡在$matches中,这样它看起来像这样:

array (size=4)
  0 => string '/foo/bar/baz' (length=12)
  1 => string '/foo' (length=4)
  2 => string '/bar' (length=4)
  3 => string '/baz' (length=4)

我错过了什么?

编辑:

如果我改用preg_match_all(),这就是输出,这仍然不是我想要的:

array (size=2)
  0 => 
    array (size=1)
      0 => string '/foo/bar/baz' (length=12)
  1 => 
    array (size=1)
      0 => string '/baz' (length=4)

这是重复捕获组的标准行为 - 它们匹配所有重复项,但只捕获最后一个重复项。请参阅正则表达式组和 * 通配符可以一起工作吗?对于使用 Python 的类似问题。我在Perl中尝试了一下,得到了相同的结果。

preg_match只抓住第一个。如果您想要所有这些,请使用preg_match_all。

但是:如果这确实是确切的用例,请改用 explode()。

也许是这样的:

preg_match_all('(/[^/]+)', $str, $matches);

您尝试使用动态捕获组做什么在某些正则表达式风格中是可能的(例如 C# - 具有可变数量的组的正则表达式?),但不幸的是在 PHP 中不是。