介绍

将字符串路径转换为正则表达式的工具。
例如 : /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 , Array, RegExp

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
* */

正则可视化:

通过以上示例,可以清晰的看清楚option中不同参数的差别:

路径参数修饰符

匹配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.

Token Information