route-path-match
Version:
compile route path template, match route path params
84 lines (79 loc) • 2.37 kB
JavaScript
/**
匹配规则
- 通配符:
- 匿名通配符: * 与 **, 前者匹配除/之外的字符,后者匹配任意字符。可以通过 *<\\d+> 的形式自定义正则,如果匹配空值需使用可选操作符 ?
- 变量通配符: :id 与 ::id 含义和用法同匿名通配符。可以通过 :id<\\d+> 的形式自定义正则
- 变量名:只支持使用驼峰形式,形如 :groupId
- 适配正则:
- 继承正则: ( ) 与 ? 等3个字符为正则的含义及用法,即分组与可选
- 自定义通配符正则: id<[0-9]+|all> 其中 < > 字符会被替换为 ( ) 其中包裹的内容会被识别为该变量的正则表达式。其中的反斜杠需要转义,如 \\d+
使用示例
- /assets/**
- /assets/**?
- /assets/::path
- /shop-*-assets/*.js
- /shop-:part-assets/:file.js
- /:lang/:group/:gid
- (/:lang)?/:group(/:gid)?
- (/:lang)?/:group/:gid(:ext<\\.(js|json)>)?
*/
/**
* @export parsePathTpl
* @export matchPathParams
*/
/**
* @desc 处理路径匹配模板到正则或字符串
* @param {string}
* @return {regexp|string}
*/
function parsePathTpl(pathTpl) {
let matcherRegexp;
let regexpMode = false;
const MATCHER_REGEXP = /([\/\[\]^$.+{}])|(\*{2,})|::([a-z][a-z0-9]*)|(\*|:([a-z][a-z0-9]*))(?:<(.*?)>)?/gi;
const replacer = (_, keychar, all, allName, one, oneName, regTpl) => {
if (keychar) {
return '\\' + keychar;
}
if (!regexpMode) {
regexpMode = true;
}
if (!regTpl) {
if (all || allName) {
regTpl = '.+?';
}
else {
regTpl = '[^/]+?';
}
}
const name = allName || oneName;
if (name) {
regTpl = `(?<${name}>${regTpl})`;
}
else {
regTpl = `(?:${regTpl})`;
}
return regTpl;
};
const pathRegexpTpl = pathTpl.replace(MATCHER_REGEXP, replacer);
if (regexpMode) {
matcherRegexp = new RegExp(`^${pathRegexpTpl}$`);
}
const pathMatcher = matcherRegexp || pathTpl;
return pathMatcher;
}
/**
* @desc 从路径匹配规则匹配路径
* @param {regexp|string} pathMatcherRule - 路由匹配规则
* @param {string} path - path of route
* @return {object|undefined}
*/
function matchPathParams(pathMatcher, path) {
if (pathMatcher.exec) {
const matched = pathMatcher.exec(path);
return matched ? matched.groups || {}: undefined;
}
else {
return pathMatcher === path ? {}: undefined;
}
}
export { matchPathParams, parsePathTpl };