正则表达式冲突,类似表达式处理

时间:2011-12-21 15:52:04

标签: php regex

首先,简单的路线添加:

# The order is as-is in my environment
Route::PATTERN('/^\/style\/(.*?)\/$/', 'style/[0].css');
Route::PATTERN('/^\/style\/(.*?)\/image-storage\/(.*?)\/$/', 'transformed/images/[1]');
Route::SIMPLE('/blog', 'parts/blog');

现在没有按优先级排序路径(如果没有别的办法可以选择,但是我想避免它),确定活动路线,扫描后执行例行程序(foreach循环路径)上面以相同的顺序添加):

foreach(self::$routes as $route){
// lookup active route
switch($route->type){
    case self::TYPE_SIMPLE:
        if($route->lookup === $_SERVER['REQUEST_URI']) self::$active = $route;
    break;
    case self::TYPE_PATTERN:
        if(preg_match_all($route->lookup, $_SERVER['REQUEST_URI'], $found)){
            // find all replaceable entries of route
            preg_match_all('/((?<=\[)\d(?=\]))/', $route->location, $replace);

            // remove first results
            $lookup = array_shift($found);
            $location = array_shift($replace);

            // make the actual location out of both
            foreach($replace[0] as $value)
                if(isset($found[$value]))
                    $route->location = str_replace('[' . $value . ']', $found[$value][0], $route->location);

            // this is active, cache it
            self::$active = $route;
        }
    break;
}
}
// I have left out the active route and routine parsing, because the problem is here at the
// case self::TYPE_PATTERN part

这里的事情是第二个模式路由与第一个匹配。我可以通过前瞻来防止这种情况,但是这些路线后来会变得动态和嵌套,因此不可预测 - 前瞻可能会/将会失败。

我对请求和查找(模式)的长度比较有所了解,但这也非常难以预料。

那么,问题是,我怎么能避免这次碰撞?

1 个答案:

答案 0 :(得分:2)

将较不通用的路线移到顶部,在另一个之上。然后,只有当它不匹配时才会尝试更普遍的:

Route::PATTERN('/^\/style\/(.*?)\/image-storage\/(.*?)\/$/', 'transformed/images/[1]');
Route::PATTERN('/^\/style\/(.*?)\/$/', 'style/[0].css');