首页 > 解决方案 > nodejs rest url中的模式匹配

问题描述

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

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

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

如何在不使用“/”拆分 url 的情况下实现这一点

提前致谢。

标签: node.jsregexpattern-matching

解决方案


参数将匹配:[^/]+,因为它后面是 a 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"]

推荐阅读