我正在查看express.js源代码,以了解它如何将命名路由参数映射到req.params
属性。
对于那些不知道的人,在express.js中,您可以使用命名参数定义路由,使它们成为可选的,只允许具有特定格式的路由(以及更多):
app.get("/user/:id/:name?/:age(\\d+)", function (req, res) {
console.log("ID is", req.params.id);
console.log("Name is", req.params.name || "not specified!");
console.log("Age is", req.params.age);
});
我意识到这个功能的核心是一个在lib/utils.jspathRegexp()
中定义的方法。方法定义如下:
function pathRegexp(path, keys, sensitive, strict) {
if (path instanceof RegExp) return path;
if (Array.isArray(path)) path = '(' + path.join('|') + ')';
path = path
.concat(strict ? '' : '/?')
.replace(/\/\(/g, '(?:/')
.replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?(\*)?/g, function (_, slash, format, key, capture, optional, star) {
keys.push({ name: key, optional: !! optional });
slash = slash || '';
return ''
+ (optional ? '' : slash)
+ '(?:'
+ (optional ? slash : '')
+ (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')'
+ (optional || '')
+ (star ? '(/*)?' : '');
})
.replace(/([\/.])/g, '\\$1')
.replace(/\*/g, '(.*)');
return new RegExp('^' + path + '$', sensitive ? '' : 'i');
}
重要的部分是第 7 行的正则表达式,/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?(\*)?/g
它以这种方式对路径名的匹配部分进行分组:
slash
the /
symbol
format I don't know what is the purpose of this one, explanation needed.
key
the word (ie. \w+
) after the :
symbol
capture
a regex written in front of the key
. Should be wrapped in parenthesis (ex. (.\\d+)
)
optional
the ?
symbol after the key
star
the *
symbol
并且回调处理程序从上面的组构建一个正则表达式。
现在的问题是,这里的目的是什么format
?
我的理解根据以下几行:
(format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)'))
并且提到的正则表达式是,
如果您.
在组之后放置一个符号slash
并且没有指定匹配条件(在括号中包裹的正则表达式key
),则生成的正则表达式匹配其余部分,path
直到它到达一个.
或/
符号。
那么有什么意义呢?
我问这个,因为:
- 我想在我的应用程序中提取和使用这个方法,并想在使用它之前完全了解它是如何工作的。
- 我在express.js文档中没有找到任何关于它的内容。
- 我只是好奇 :)