PHP - Preg匹配多个条件

时间:2017-04-29 11:45:22

标签: php regex preg-match

我有以下字符串:

"#(admin/pages|admin/pages/add|admin/pages/[0-9]+)#"

将此字符串与之比较:

"admin/pages/1"

在使用admin/pages/1比较2个字符串时,我需要返回“preg_match()”。我有以下代码,它不起作用:

if(preg_match("#(admin/pages|admin/pages/add|admin/pages/[0-9]+)#", "admin/pages/1", $matches) {
   var_dump($matches); 
}

这是我得到的输出:

array(2) { [0]=> string(11) "admin/pages" [1]=> string(11) "admin/pages" }

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:1)

将正则表达式更改为:

"#(admin/pages(?:/\d+)?|admin/pages/add)#"

如果将数字放在第一个模式中并使它们成为可选项,则不需要两个变体(admin/pages|admin/pages/[0+9]+)。

默认情况下,问号和重复是贪婪的,这就是为什么它总是包含我的版本匹配中的数字。
另一方面,如果你有一个轮换,它将始终选择第一场比赛。由于您的第一次轮换不包括数字,因此它们不匹配。

如果您还想知道为什么两次获得比赛,那是因为preg_match的工作方式。
从文档中引用:

  

$ matches [0]将包含与完整模式匹配的文本,   $ matches [1]将具有与第一个捕获的匹配的文本   带括号的子模式,依此类推。

如果整个匹配足够,您可以删除外括号:

"#admin/pages(?:/\d+)?|admin/pages/add#"

只需使用$matches[0]即可。

而且,正如@RomanPerekhrest写的那样,我无耻地包含在这个答案中,你可以缩短你的模式。您不需要多次包含admin/pages

"#admin/pages(?:/add|/\d+)?#"

答案 1 :(得分:1)

使用以下短正则表达式:

"#admin/pages(/add|/[0-9]+)?#"

(/add|/[0-9]+)? - 可选的替代组,如果发生,则匹配搜索子字符串末尾的/add/<number>

答案 2 :(得分:0)

尝试更改组件的顺序:

"#(admin/pages/[0-9]+|admin/pages/add|admin/pages)#"

一旦匹配,就会满足正则表达式。在您的情况下,它会在找到admin/pages后立即停止,而不再进一步查看。