nodejs静态网址中的模式匹配

时间:2019-01-17 23:50:31

标签: node.js regex pattern-matching

在我的节点应用程序中,我正在使用router.use进行令牌验证。 我想跳过一些网址的验证,所以我想检查网址是否匹配,然后调用next();

但是我要跳过的URL有一个URLparam

例如,这是URL / service /:appname / getall。 必须将其与 / service / blah / getall 匹配并给出真实的结果。

如何在不使用'/'分隔网址的情况下实现该目标

谢谢。

1 个答案:

答案 0 :(得分:2)

参数将与:[^/]+匹配,因为它是:后面跟着/以外的1次或多次。

如果您在模板中找到参数,然后将其替换为匹配任何字符串的正则表达式,就可以按照您的要求进行操作。

let template = '/service/:appname/getall'
let url = '/service/blah/getall'

// find params and replace them with regex
template = template.replace(/:[^/]+/g, '([^/]+)')

// the template is now a regex string '/service/[^/]+/getall'
// which is essentially '/service/ ANYTHING THAT'S NOT A '/' /getall'

// convert to regex and only match from start to end
template = new RegExp(`^${template}$`)

// ^ = beggin
// $ = end
// the template is now /^\/service\/([^\/]+)\/getall$/

matches = url.match(template)
// matches will be null is there is no match.

console.log(matches)
// ["/service/blah/getall", "blah"]
// it will be [full_match, param1, param2...]

编辑:使用\w代替[^/] ,因为:

  

路由参数的名称必须由“单词字符”([A-Za-z0-9_])组成。 https://expressjs.com/en/guide/routing.html#route-parameters

我相信大多数解析器都是如此,因此我更新了答案。以下测试数据仅适用于此更新的方法。

let template = '/service/:app-:version/get/:amt';
let url = '/service/blah-v1.0.0/get/all';

template = template.replace(/:\w+/g, `([^/]+)` );

template = new RegExp(`^${template}$`);
let matches = url.match(template);

console.log(url);
console.log(template);
console.log(matches);
// Array(4) ["/service/blah-v1.0.0/get/all", "blah", "v1.0.0", "all"]