PHP - 用于路由的正则表达式

标签 php regex

我正在尝试创建一个模拟正则表达式模式来过滤类似 Laravel 的路由,但我无法弄清楚我的正则表达式。我想替换路由中的 {variable} 并将其与 uri 匹配。

示例:

路线:

 /user/{id}
 /user/{id}/edit

URI:

/user/1
/user/1/edit

当前代码(以下代码位于遍历路由的 foreach 循环中)

//escape slashes
$pattern = '/^' . str_replace("/", '\/', $route) . '$/i';
//strip out variables from route to compare with uri
$pattern = preg_replace('/\{(.*?)\}/', '(.*?)', $pattern);

if (preg_match($pattern, $uri)){
     echo "Found a match.";
}

问题是,当在浏览器中输入上面的第二个 uri(/user/1/edit) 时,它将与第一个路由匹配,而不是与第二个路由匹配。我假设是因为我用 (.*?) 替换了变量({id}),所以它将匹配变量后面的任何内容。

最佳答案

问题可能是demonstrated as thus (这是一个实际的最小测试用例,请努力创建它们!)

preg_match("{^/(.*?)/(.*?)/$}", "/foo/bar/", $matches);
var_dump($matches);    // captures -> "foo", "bar"

preg_match("{^/(.*?)/$}", "/foo/bar/", $matches);
var_dump($matches);    // captures -> "foo/bar"

这是因为非贪婪的“?”限定符表示“在仍然尽最大努力进行匹配的同时,尽可能少地匹配可以”。在第二种情况下,正则表达式引擎首先尝试仅匹配“foo”,然后由于模式失败,正则表达式回溯并且捕获被迫捕获“foo/酒吧”。

解决方案是禁止该组织捕获任何不允许捕获的东西。

preg_match("{^/([^/]+)/$}", "/foo/bar/", $matches);
var_dump($matches);    // match failed

关于PHP - 用于路由的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25734988/

相关文章:

php - 使用表锁防止并行执行 (MySQL)

php - 如何使用转义字符拆分以空格分隔的 token 字符串?

php - 关闭 php 标签时出错

regex - R 使用 tidyr::separate 在最后一个空白字符处拆分字符串

javascript - 正则表达式 : Positive and Negative Lookahead Solution

ruby-on-rails - 正则表达式新手

php - 在 ubuntu 12.04 上进行 Alfresco 安装,并使用现有的 efront 部署

php - PHP中大括号之间的匹配文本

python - 用其他字符替换前导空格 - Python

c# - 正则表达式查找 css 引用