【问题标题】:How to make my regex only return exact matches如何让我的正则表达式只返回完全匹配
【发布时间】:2012-12-19 19:46:40
【问题描述】:

我正在考虑在 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”这样的 url 时,我会返回相应的函数名称(现在只需弄清楚如何将字符串作为函数调用)。问题是如果我有两条非常相似的路线,就像我的示例中的正则表达式匹配两者一样。在上面的示例中,理想情况下,我只希望匹配第二条路线,但不幸的是两者都匹配,因为当然第一条路线也是匹配的。

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

【问题讨论】:

    标签: javascript regex


    【解决方案1】:

    试试这个:

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

    如果您还想支持尾随 / 来覆盖 /users/1024/pictures/456/,您可以按如下方式更改您的 RegExp:

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

    【讨论】:

      【解决方案2】:

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

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

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

      如果你是从window.location.pathname 的路径进行匹配,那么它可能是可以的。

      【讨论】:

        【解决方案3】:

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

        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"]
        }
        */
        

        【讨论】:

        • 谢谢。我的只是为了看看我能不能得到一些工作。会添加 hasOwnProperty 等,但就像路由缓存在匹配器对象中的方式一样。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-16
        • 1970-01-01
        • 2023-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多