path-to-regexp
在vue-router/react-router/koa-router等路由工具中,定义路由格式形如:/user/:name 或者其他更复杂的路由匹配。其实现均依赖path-to-regexp.js,本章将和读者一起深入探究path-to-regexp实现原理,同时加强对正则表达式的理解
path-to-regex项目地址https://github.com/pillarjs/path-to-regexp
使用方法
const pathToRegexp = require('path-to-regexp')
// pathToRegexp(path, keys?, options?)
// pathToRegexp.parse(path)
// pathToRegexp.compile(path)path 字符串/字符串数组/正则表达式
keys path路径中捕获到的匹配项等
options 配置项
sensitive 如果为
true正则表达式大小写敏感 (默认:false)strict 如果为
true正则表达式允许可选的尾随分隔符匹配 (default:false)end 如果为
true正则表达式将从字符串的结尾匹配 (default:true)start 如果为
true正则表达式将从字符串的开头匹配 (default:true)delimiter 默认分割符号 (default:
'/')endsWith Optional character, or list of characters, to treat as "end" characters
whitelist 解析时要考虑分隔符的字符列表 (default:
undefined, any character)
暴露函数
使用module.exports对模块外暴露下述方法
全局变量
全局变量中定义了路由默认分割符,以及路由匹配模式

从上述正则可视化图中可知,该正则匹配可拆分为3种子正则表达式,分别是:“(\\\\.)”,“(?:\\:(\\w+)(?:\\(((?:\\\\.|)+)\\))?)([+*?])?”,“(?:\\(((?:\\\\.|)+)\\))([+*?])?”;以下分别举例讲解:
匹配转义模式
匹配字符串中包含转义\字符的路径,如:"/user/\\?"
匹配命名路由参数,即:包含:key关键字模式
该匹配模式中,有2种子类型匹配模式,分别是:key,以及限制key模式的正则;可匹配路径,如:“/user/:id”,“/user/:id?”,“/user/:id(\\d{8})”,“/user/:id(\\d{8})?”,其中:key(),括号中的为正则表达式字符串
匹配无命名路由参数,即:不包含:key关键字模式
该模式可匹配模式,如:/user/([\d]{8}),/user/([\d]{8})?
公共函数
path-to-regexp中包含2个对字符串进行编码的函数:escapeString,escapeGroup
escapeString,对正则中所有特殊字符进行编码
escapeGroup,对路由参数中自定义正则表达式进行编码
规定,在路由参数自定义正则表达式中不能存在=!:$/()等正则字符,固把这些字符进行转义
核心方法讲解
首先通过一个例子,了解pathToRegexp的输入和输出,如下输入“/user/:id(\d{8})?”时,输出“/^\/user(?:\/(\d{8}))?(?:\/)?$/i”
pathToRegexp 处理流程
从下图可知,path解析为tokens(parse)与tokens转换为正则(tokensToRegExp)为核心逻辑,接下来的章节将围绕这两个函数进行讲解

parse
该函数把path路径解析为tokens数组,其中tokens结构为:
从上述结构可知,tokens由n个token组成,其中每个token中的元素由路由执行正则PATH_REGEXP匹配并捕获而得到,那么匹配捕获项怎么和token对应起来呢?见示列:
见如下源码:
tokensToRegExp
该函数,把tokens数组转为路由正则表达式,继5.2. 中得到tokens,转换为正则表达式如下:
见下述,通过分析源码,了解tokens转为正则的实现细节
Last updated
Was this helpful?