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

PHP正则表达式-多组捕获的奇怪问题,php,regex,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

守则:

$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"
}*/
$pattern='~(/(?Pen | ru))?/foo(/(?Pbar))?~;
预匹配($pattern,'/foo',$matches);
var_dump($matches);
/*输出:
阵列(1){
[0] =>
字符串(4)“/foo”
}*/
预匹配($pattern,'/foo/bar',$matches);
var_dump($matches);
/*输出:
阵列(7){
[0] =>
字符串(8)“/foo/bar”
[1] =>
字符串(0)”
“郎”=>
字符串(0)”
[2] =>
字符串(0)”
[3] =>
字符串(4)“/bar”
'酒吧'=>
字符串(3)“bar”
[4] =>
字符串(3)“bar”
}*/
问题是:为什么它会在第二个preg_match调用中捕获
,我该如何修复它


另外,我在上面尝试了这个正则表达式,它捕捉到了正确的结果,但是在我的PHP7机器上,它没有。我觉得regex101会过滤输出。

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

在PHP中,使用
$matches
上的
array\u filter
删除空条目

此外,我建议使用非捕获组
(?:)
来消除混乱:

(?:/(?Pen|ru))?/foo(?:/(?Pbar))?


或者把它分成两个正则表达式:
(?:/(?Pen | ru))
/foo(?:/(?Pbar))

不知道你的意思,但是惰性匹配可能会有所帮助:
(?Pen | ru))?/foo(/(?Pbar))?
我的意思是当没有匹配时,它不应该捕获
lang
。这没有任何意义。不,添加另一个
没有帮助。请澄清。我在您的代码演示中看到
lang
是空的:
'lang'=>string(0)”
。没有捕获任何文本…欢迎使用PHP:-DAnd查看:如果在选项中启用“显示非参与组”,您将在右侧看到所有组信息。默认行为只是隐藏它们。