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

时间:2012-08-11 04:20:10

标签: php regex

给出以下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)

4 个答案:

答案 0 :(得分:1)

这是重复捕获组的标准行为 - 它们匹配所有重复,但只捕获最后一个。有关使用Python的类似问题,请参阅Can Regex groups and * wildcards work together?。我在Perl中尝试了它并获得了相同的结果。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

也许是这样的:

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

答案 3 :(得分:0)

您在尝试使用动态捕获组时可以使用某些正则表达式(例如C# - Regular expression with variable number of groups?),但遗憾的是不能在PHP中使用。