我正在寻找在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”这样的网址时,我会找回相应的函数名称(现在只需要解决如何将字符串作为函数调用)。问题是如果我有两个非常相似的路由,在我的例子中正则表达式匹配两者。在上面的例子中,我理想情况下只喜欢匹配的第二条路线但不幸的是两条路线都匹配,因为当然第一条路线也匹配。
有什么方法可以让正则表达式只返回完全匹配?我有另一个解决方案,它将涉及计算输入网址中的正斜杠,并且仅调用具有匹配数量的正斜杠的路线....但这似乎相当不优雅。
答案 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"]
}
*/