如何使我的正则表达式只返回完全匹配

时间:2012-12-19 10:18:36

标签: javascript regex

我正在寻找在javaScript中构建一个超级简单的路由器......到目前为止,我有这个:

var match,routeMatcher,p;

var routes = {
    "/users/:uid/pictures/:uid" : "userpictures",
    "/users/:uid" : "user"
};

var url = "/users/1024/pictures/456";

for(var i in routes) {
    //need to cache this regex
    routeMatcher = new RegExp(i.replace(/:[^\s/]+/g, '([\\w-]+)'));
    if(url.match(routeMatcher)) {
        match = url.match(routeMatcher);
        p = routes[i];
        console.log(p);
    }
}

这是一个小提琴http://jsfiddle.net/D6txe/

这很有效。当我输入像“users / 1000”这样的网址时,我会找回相应的函数名称(现在只需要解决如何将字符串作为函数调用)。问题是如果我有两个非常相似的路由,在我的例子中正则表达式匹配两者。在上面的例子中,我理想情况下只喜欢匹配的第二条路线但不幸的是两条路线都匹配,因为当然第一条路线也匹配。

有什么方法可以让正则表达式只返回完全匹配?我有另一个解决方案,它将涉及计算输入网址中的正斜杠,并且仅调用具有匹配数量的正斜杠的路线....但这似乎相当不优雅。

2 个答案:

答案 0 :(得分:2)

我不完全确定这是否是您所需要的。

我使用^$使正则表达式匹配网址路径部分的确切格式:

routeMatcher = new RegExp("^" + i.replace(/:[^\s\/]+/g, '([\\w-]+)') + "$");

如果您从window.location.pathname开始进行匹配,那么它可能就行了。

答案 1 :(得分:2)

这是一个缓存正则表达式的变体(请注意正则表达式中的'^''$'):

function Router(routes) {
    var route, routeExp, matchers = {};

    for (route in routes) {
        if (routes.hasOwnProperty(route)) {
            routeExp = '^' + route.replace(/:[^\s/]+/g, '([\\w-]+)') + '$';
            matchers[route] = new RegExp(routeExp);
        }
    }

    return function(url) {
        var match;
        for (route in matchers) {
            if (matchers.hasOwnProperty(route)) {
                if (match = url.match(matchers[route])) {
                    return {
                        route: route,
                        name: routes[route],
                        match: match.slice(1)
                    };
                }
            }
        }
    }
}

用法:

var router = new Router({
    "/users/:uid/pictures/:uid" : "userpictures",
    "/users/:uid" : "user"
});

var result = router("/users/1024/pictures/456");

console.log(result);
/*
{
    route: "/users/:uid/pictures/:uid",
    name: "userpictures"
    match: ["1024", "456"]
}
*/