代码:
$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过滤了输出。
答案 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))
。