介绍
将字符串路径转换为正则表达式的工具。
例如 : /user/:id
转换为 /^\/user\/((?:[^\/]+?))(?:\/(?=$))?$/i
使用path-to-regexp的项目
react-router就依赖path-to-regexp,清楚了path-to-regexp的规则,自然就明白了Route组件中exact、strict和sensitive的作用。
同时看到 express,koa-router,next等许多成熟的框架也都依赖该组件。
Installation
npm install path-to-regexp --save
Usage
var pathToRegexp = require('path-to-regexp')
// pathToRegexp(path, keys?, options?)
// pathToRegexp.parse(path)
// pathToRegexp.compile(path)
- path string|RegExp|Array
- keys Array
- options Object
- sensitive 如果值为true,则大小写敏感,默认为false。
- strict 如果值为false,则可省略最后的斜杠,默认为false。
- end 如果值为false,则只匹配是否以给定的路径开头,默认为true。
- 高级选项,用于处理非路径(pathname)部分, 例如 主机名(hostname)等:
delimiter The default delimiter for segments. (default:'/'
)
endsWith Optional character, or list of characters, to treat as "end" characters.
delimiters List of characters to consider delimiters when parsing. (default:'./'
)
参数
path
String , Array
keys
将在path中解析到的参数名追加到keys后。
keys必须是一个数组。
类似C#中的ref参数。
var keys = [1,2]
var re = pathToRegexp('/foo/:bar', keys)
// re = /^\/foo\/([^\/]+?)\/?$/i
// keys = [1,2,{ name: 'bar', prefix: '/', delimiter: '/', optional: false, repeat: false, pattern: '[^\\/]+?' }]
options
import path2reg from 'path-to-regexp'
var keys = [];
var path = '/user/:id';
path2reg(path, key, {sensitive: false, end: false, strict: false});
path2reg(path, key, {sensitive: true, end: false, strict: false});
path2reg(path, key, {sensitive: false, end: true, strict: false});
path2reg(path, key, {sensitive: false, end: false, strict: true});
path2reg(path, key, {sensitive: false, end: true, strict: true});
/*
/^\/user\/((?:[^\/]+?))(?:\/(?=$))?(?=\/|$)/i
/^\/user\/((?:[^\/]+?))(?:\/(?=$))?(?=\/|$)/
/^\/user\/((?:[^\/]+?))(?:\/(?=$))?$/i
/^\/user\/((?:[^\/]+?))(?=\/|$)/i
/^\/user\/((?:[^\/]+?))$/i
* */
正则可视化:
- {sensitive: false, end: false, strict: false}
- {sensitive: true, end: false, strict: false}
- {sensitive: false, end: true, strict: false}
- {sensitive: false, end: false, strict: true}
- {sensitive: false, end: true, strict: true}
通过以上示例,可以清晰的看清楚option中不同参数的差别:
- {sensitive:true},返回的正则会添加标识i。
- {end:true},正则结尾的
(?=\/|$)
换成了$
。 即:
为true时,则完整匹配整个路径,path参数指定了完整的路径格式。例如:/user/:id
,可以匹配/user/1
或/user/1/
,但不能匹配/user/1/2
。
为false时,相当于path参数只指定了路径的开头部分,例如:/user/:id
,可以匹配/user/1
或/user/1/2
。 - {strict:true},缺少倒数第二个分组:
(?:\/(?=$))?
。
即对于/user/1/
,在strict:true时,匹配结果为/user/1
,为false时,匹配结果为:/user/1/
。
只设置strict为true,则影响不大,一般strict和end参数会配合使用。 - {end:true,strict:true}, 则
/user/:id
只能匹配/user/1
,不能匹配/user/1/
或/user/1/2
。
当end和strict都为true,end判断当前为完整匹配,所以不匹配/user/1/2
。
strict判断结尾是否可以有斜线,所以不匹配/user/1/
。
路径参数修饰符
匹配0次或1次。
var re = pathToRegexp('/:foo/:bar?')
// keys = [{ name: 'foo', ... }, { name: 'bar', delimiter: '/', optional: true, repeat: false }]
re.exec('/test')
//=> ['/test', 'test', undefined]
re.exec('/test/route')
//=> ['/test', 'test', 'route']
匹配0次或多次
var re = pathToRegexp('/:foo*')
// keys = [{ name: 'foo', delimiter: '/', optional: true, repeat: true }]
re.exec('/')
//=> ['/', undefined]
re.exec('/bar/baz')
//=> ['/bar/baz', 'bar/baz']
匹配一次或多次
var re = pathToRegexp('/:foo+')
// keys = [{ name: 'foo', delimiter: '/', optional: false, repeat: true }]
re.exec('/')
//=> null
re.exec('/bar/baz')
//=> ['/bar/baz', 'bar/baz']
自定义正则
默认,参数匹配的内容为: [^\/]+?
,可以通过括号包裹一个自定义的正则。
pathToRegexp('/user/:id(\\d+)',[],{sensitive: false, end: true, strict: true})
// /^\/user\/((?:\d+))$/i
pathToRegexp('/user/:id',[],{sensitive: false, end: true, strict: true})
// /^\/user\/((?:[^\/]+?))$/i
或者匿名参数形式:
pathToRegexp('/user/(\\d+)',[],{sensitive: false, end: true, strict: true})
// /^\/user\/((?:\d+))$/i
Parse
The parse function is exposed via pathToRegexp.parse
. This will return an array of strings and keys.
var tokens = pathToRegexp.parse('/route/:foo/(.*)')
console.log(tokens[0])
//=> "/route"
console.log(tokens[1])
//=> { name: 'foo', prefix: '/', delimiter: '/', optional: false, repeat: false, pattern: '[^\\/]+?' }
console.log(tokens[2])
//=> { name: 0, prefix: '/', delimiter: '/', optional: false, repeat: false, pattern: '.*' }
Note: This method only works with strings.
Compile ("Reverse" Path-To-RegExp)
Path-To-RegExp exposes a compile function for transforming a string into a valid path.
var toPath = pathToRegexp.compile('/user/:id')
toPath({ id: 123 }) //=> "/user/123"
toPath({ id: 'café' }) //=> "/user/caf%C3%A9"
toPath({ id: '/' }) //=> "/user/%2F"
toPath({ id: ':/' }) //=> "/user/%3A%2F"
toPath({ id: ':/' }, { encode: (value, token) => value }) //=> "/user/:/"
var toPathRepeated = pathToRegexp.compile('/:segment+')
toPathRepeated({ segment: 'foo' }) //=> "/foo"
toPathRepeated({ segment: ['a', 'b', 'c'] }) //=> "/a/b/c"
var toPathRegexp = pathToRegexp.compile('/user/:id(\\d+)')
toPathRegexp({ id: 123 }) //=> "/user/123"
toPathRegexp({ id: '123' }) //=> "/user/123"
toPathRegexp({ id: 'abc' }) //=> Throws `TypeError`.
Note: The generated function will throw on invalid input. It will do all necessary checks to ensure the generated path is valid. This method only works with strings.
Working with Tokens
Path-To-RegExp exposes the two functions used internally that accept an array of tokens.
pathToRegexp.tokensToRegExp(tokens, keys?, options?)
Transform an array of tokens into a matching regular expression.pathToRegexp.tokensToFunction(tokens)
Transform an array of tokens into a path generator function.
Token Information
name
The name of the token (string
for named ornumber
for index)prefix
The prefix character for the segment (/
or.
)delimiter
The delimiter for the segment (same as prefix or/
)optional
Indicates the token is optional (boolean
)repeat
Indicates the token is repeated (boolean
)partial
Indicates this token is a partial path segment (boolean
)pattern
The RegExp used to match this token (string
)