正则表达式正好反对我想做什么吗?

时间:2012-07-18 14:48:22

标签: javascript regex node.js webserver

我正在创建一个可重用的node.js NavigationController 类,所以我可以在其他服务器端项目中重用它。如果我可能需要或其他人可能觉得它有用。

这是用例。

var navController = new NavigationController({
    routes : {
        '/user/:action/:anything' : 'UserController',
        '/app/:action' : 'AppController',
        '/file/:action' : 'FileController',
        '/feedback/:action' : 'FeedbackController',
        '/:anything' : 'ErrorController'
    },
    ErrorController : 'ErrorController'
});
navController.init();

服务器请求的用户可以调用该对象的此功能。

navController.navigate(req, res);

现在正确调用此控制器和控制器。 导航(req,res)函数下的内容是基于URL调用适当控制器对象的一部分,定义为名为 getRouteByPath(path)的函数。此私有函数将获取路径并允许导航(req,res)函数以获取要调用的控制器类名称。

var getRouteByPath = function(path) {
    for(var route in config.routes) {
        var routeRegex = '';

        var routeParts = route.split('/');

        for(var rp = 0; rp < routeParts.length; rp++) {

            // checking if route part starts with :
            if(routeParts[rp].indexOf(':') === 0) {

                // this is "anything" part
                routeRegex += '[/]?([A-Za-z0-9]*)';

            } else if(routeParts[rp] != "") {
                routeRegex += '[/]?' + routeParts[rp];
            }
        }

        var routeRegexResult = path.match(routeRegex);
        if(routeRegexResult) {
            console.log(routeRegexResult);
            return route;
        }
    }
    return null;
};

我太担心这个功能,好像这是正确的方法吗?

2 个答案:

答案 0 :(得分:2)

一些缺陷:

  • 为什么使用斜杠作为字符类([/])?不需要这样做,只有在正则表达式文字中,你需要用反斜杠来逃避它(比如/\//g)。只需使用一个“/”代替(new RegExp("/", "g"))。

  • .indexOf(<string>)==0确实有效,但搜索整个字符串并且效率不高。在您的情况下routePart.charAt(0)==":"

  • ,最好使用startswith
  • <string>.match(<string>) - 我建议您制作一个新的RegExp object并使用.test,因为您不想匹配 - 也没有我认为需要建立捕获组,因为你只返回路由字符串但没有匹配(好吧,你记录它们)。

  • 您想检查整个path是否与正则表达式匹配?别忘了添加^$。您当前的AppController正则表达式也匹配/user/app/example

  • 之类的路由
  • 为什么你的斜线(和斜线)是可选的(/?)?不仅我不认为这是你想要的,而且在构建像/\/?user\/?([A-Za-z0-9]*)\/?([A-Za-z0-9]*)/

    这样的正则表达式时,它也为catastrophic backtracking打开了大门。

    要逃避这种情况,您需要将整个群组设为可选:(?:/([^/]*))?

  • 此外,您应该只构建一次正则表达式(在初始化时)并将它们存储在缓存中,而不是在每次调用getRouteByPath时构建它们。 RegExp的编译隐藏在您的代码中,尽管它需要发生。

答案 1 :(得分:0)

一些注意事项:

routeRegex += '[/]?([A-Za-z0-9]*)';

表示路线可能存在,也可能不存在//匹配,+可能比*更合适。

此外,由于我在网络路径中允许_

您的.split('/')会从路线中移除所有/,因此不应该在拆分列表中