PHP正则表达式 - 多组捕获的奇怪问题

时间:2016-04-04 13:48:26

标签: php regex

代码:

$pattern = '~(/(?P<lang>en|ru))?/foo(/(?P<bar>bar))?~';

preg_match($pattern, '/foo', $matches);
var_dump($matches);
/*output:
array(1) {
  [0] =>
  string(4) "/foo"
}*/
preg_match($pattern, '/foo/bar', $matches);
var_dump($matches);
/*output:
array(7) {
  [0] =>
  string(8) "/foo/bar"
  [1] =>
  string(0) ""
  'lang' =>
  string(0) ""
  [2] =>
  string(0) ""
  [3] =>
  string(4) "/bar"
  'bar' =>
  string(3) "bar"
  [4] =>
  string(3) "bar"
}*/

问题:为什么它会在第二次preg_match调用中捕获<lang>以及如何解决它?

P.S。我在https://www.regex101.com上尝试了这个正则表达式并且它正确地捕获了,但是在我的PHP7机器上,它没有。我感觉regex101过滤了输出。

1 个答案:

答案 0 :(得分:1)

正如其他人所说,这就是正则表达式的工作方式。据我所知,它对正则表达式来说相当普遍。它甚至在编程中也有相似之处,例如Java如何需要String返回函数来返回String(除非它抛出错误)。

在PHP中,使用array_filter上的$matches删除空条目。

另外,我建议使用非捕获组(?:)来减少混乱:

(?:/(?P<lang>en|ru))?/foo(?:/(?P<bar>bar))?

或者将其拆分为2个正则表达式:(?:/(?P<lang>en|ru))/foo(?:/(?P<bar>bar))