Giter Club home page Giter Club logo

path-to-regexp's Introduction

Path-to-RegExp

Turn a path string such as /user/:name into a regular expression.

NPM version NPM downloads Build status Build coverage License

Installation

npm install path-to-regexp --save

Usage

const { pathToRegexp, match, parse, compile } = require("path-to-regexp");

// pathToRegexp(path, keys?, options?)
// match(path)
// parse(path)
// compile(path)

Path to regexp

The pathToRegexp function will return a regular expression object based on the provided path argument. It accepts the following arguments:

  • path A string, array of strings, or a regular expression.
  • keys (optional) An array to populate with keys found in the path.
  • options (optional)
    • sensitive When true the regexp will be case sensitive. (default: false)
    • strict When true the regexp won't allow an optional trailing delimiter to match. (default: false)
    • end When true the regexp will match to the end of the string. (default: true)
    • start When true the regexp will match from the beginning of the string. (default: true)
    • delimiter The default delimiter for segments, e.g. [^/#?] for :named patterns. (default: '/#?')
    • endsWith Optional character, or list of characters, to treat as "end" characters.
    • encode A function to encode strings before inserting into RegExp. (default: x => x)
    • prefixes List of characters to automatically consider prefixes when parsing. (default: ./)
const keys = [];
const regexp = pathToRegexp("/foo/:bar", keys);
// regexp = /^\/foo(?:\/([^\/#\?]+?))[\/#\?]?$/i
// keys = [{ name: 'bar', prefix: '/', suffix: '', pattern: '[^\\/#\\?]+?', modifier: '' }]

Please note: The RegExp returned by path-to-regexp is intended for ordered data (e.g. pathnames, hostnames). It can not handle arbitrarily ordered data (e.g. query strings, URL fragments, JSON, etc). When using paths that contain query strings, you need to escape the question mark (?) to ensure it does not flag the parameter as optional.

Parameters

The path argument is used to define parameters and populate keys.

Named Parameters

Named parameters are defined by prefixing a colon to the parameter name (:foo).

const regexp = pathToRegexp("/:foo/:bar");
// keys = [{ name: 'foo', prefix: '/', ... }, { name: 'bar', prefix: '/', ... }]

regexp.exec("/test/route");
//=> [ '/test/route', 'test', 'route', index: 0, input: '/test/route', groups: undefined ]

Please note: Parameter names must use "word characters" ([A-Za-z0-9_]).

Custom Matching Parameters

Parameters can have a custom regexp, which overrides the default match ([^/]+). For example, you can match digits or names in a path:

const regexpNumbers = pathToRegexp("/icon-:foo(\\d+).png");
// keys = [{ name: 'foo', ... }]

regexpNumbers.exec("/icon-123.png");
//=> ['/icon-123.png', '123']

regexpNumbers.exec("/icon-abc.png");
//=> null

const regexpWord = pathToRegexp("/(user|u)");
// keys = [{ name: 0, ... }]

regexpWord.exec("/u");
//=> ['/u', 'u']

regexpWord.exec("/users");
//=> null

Tip: Backslashes need to be escaped with another backslash in JavaScript strings.

Custom Prefix and Suffix

Parameters can be wrapped in {} to create custom prefixes or suffixes for your segment:

const regexp = pathToRegexp("/:attr1?{-:attr2}?{-:attr3}?");

regexp.exec("/test");
// => ['/test', 'test', undefined, undefined]

regexp.exec("/test-test");
// => ['/test', 'test', 'test', undefined]

Unnamed Parameters

It is possible to write an unnamed parameter that only consists of a regexp. It works the same the named parameter, except it will be numerically indexed:

const regexp = pathToRegexp("/:foo/(.*)");
// keys = [{ name: 'foo', ... }, { name: 0, ... }]

regexp.exec("/test/route");
//=> [ '/test/route', 'test', 'route', index: 0, input: '/test/route', groups: undefined ]

Modifiers

Modifiers must be placed after the parameter (e.g. /:foo?, /(test)?, /:foo(test)?, or {-:foo(test)}?).

Optional

Parameters can be suffixed with a question mark (?) to make the parameter optional.

const regexp = pathToRegexp("/:foo/:bar?");
// keys = [{ name: 'foo', ... }, { name: 'bar', prefix: '/', modifier: '?' }]

regexp.exec("/test");
//=> [ '/test', 'test', undefined, index: 0, input: '/test', groups: undefined ]

regexp.exec("/test/route");
//=> [ '/test/route', 'test', 'route', index: 0, input: '/test/route', groups: undefined ]

Tip: The prefix is also optional, escape the prefix \/ to make it required.

When dealing with query strings, escape the question mark (?) so it doesn't mark the parameter as optional. Handling unordered data is outside the scope of this library.

const regexp = pathToRegexp("/search/:tableName\\?useIndex=true&term=amazing");

regexp.exec("/search/people?useIndex=true&term=amazing");
//=> [ '/search/people?useIndex=true&term=amazing', 'people', index: 0, input: '/search/people?useIndex=true&term=amazing', groups: undefined ]

// This library does not handle query strings in different orders
regexp.exec("/search/people?term=amazing&useIndex=true");
//=> null
Zero or more

Parameters can be suffixed with an asterisk (*) to denote a zero or more parameter matches.

const regexp = pathToRegexp("/:foo*");
// keys = [{ name: 'foo', prefix: '/', modifier: '*' }]

regexp.exec("/");
//=> [ '/', undefined, index: 0, input: '/', groups: undefined ]

regexp.exec("/bar/baz");
//=> [ '/bar/baz', 'bar/baz', index: 0, input: '/bar/baz', groups: undefined ]
One or more

Parameters can be suffixed with a plus sign (+) to denote a one or more parameter matches.

const regexp = pathToRegexp("/:foo+");
// keys = [{ name: 'foo', prefix: '/', modifier: '+' }]

regexp.exec("/");
//=> null

regexp.exec("/bar/baz");
//=> [ '/bar/baz','bar/baz', index: 0, input: '/bar/baz', groups: undefined ]

Match

The match function will return a function for transforming paths into parameters:

// Make sure you consistently `decode` segments.
const fn = match("/user/:id", { decode: decodeURIComponent });

fn("/user/123"); //=> { path: '/user/123', index: 0, params: { id: '123' } }
fn("/invalid"); //=> false
fn("/user/caf%C3%A9"); //=> { path: '/user/caf%C3%A9', index: 0, params: { id: 'café' } }

The match function can be used to custom match named parameters. For example, this can be used to whitelist a small number of valid paths:

const urlMatch = match("/users/:id/:tab(home|photos|bio)", {
  decode: decodeURIComponent,
});

urlMatch("/users/1234/photos");
//=> { path: '/users/1234/photos', index: 0, params: { id: '1234', tab: 'photos' } }

urlMatch("/users/1234/bio");
//=> { path: '/users/1234/bio', index: 0, params: { id: '1234', tab: 'bio' } }

urlMatch("/users/1234/otherstuff");
//=> false

Process Pathname

You should make sure variations of the same path match the expected path. Here's one possible solution using encode:

const fn = match("/café", { encode: encodeURI });

fn("/caf%C3%A9"); //=> { path: '/caf%C3%A9', index: 0, params: {} }

Note: URL encodes paths, so /café would be normalized to /caf%C3%A9 and match in the above example.

Alternative Using Normalize

Sometimes you won't have already normalized paths to use, so you could normalize it yourself before matching:

/**
 * Normalize a pathname for matching, replaces multiple slashes with a single
 * slash and normalizes unicode characters to "NFC". When using this method,
 * `decode` should be an identity function so you don't decode strings twice.
 */
function normalizePathname(pathname: string) {
  return (
    decodeURI(pathname)
      // Replaces repeated slashes in the URL.
      .replace(/\/+/g, "/")
      // Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize
      // Note: Missing native IE support, may want to skip this step.
      .normalize()
  );
}

// Two possible ways of writing `/café`:
const re = pathToRegexp("/caf\u00E9");
const input = encodeURI("/cafe\u0301");

re.test(input); //=> false
re.test(normalizePathname(input)); //=> true

Parse

The parse function will return a list of strings and keys from a path string:

const tokens = parse("/route/:foo/(.*)");

console.log(tokens[0]);
//=> "/route"

console.log(tokens[1]);
//=> { name: 'foo', prefix: '/', suffix: '', pattern: '[^\\/#\\?]+?', modifier: '' }

console.log(tokens[2]);
//=> { name: 0, prefix: '/', suffix: '', pattern: '.*', modifier: '' }

Note: This method only works with strings.

Compile ("Reverse" Path-To-RegExp)

The compile function will return a function for transforming parameters into a valid path:

// Make sure you encode your path segments consistently.
const toPath = compile("/user/:id", { encode: encodeURIComponent });

toPath({ id: 123 }); //=> "/user/123"
toPath({ id: "café" }); //=> "/user/caf%C3%A9"
toPath({ id: ":/" }); //=> "/user/%3A%2F"

// Without `encode`, you need to make sure inputs are encoded correctly.
// (Note: You can use `validate: false` to create an invalid paths.)
const toPathRaw = compile("/user/:id", { validate: false });

toPathRaw({ id: "%3A%2F" }); //=> "/user/%3A%2F"
toPathRaw({ id: ":/" }); //=> "/user/:/"

const toPathRepeated = compile("/:segment+");

toPathRepeated({ segment: "foo" }); //=> "/foo"
toPathRepeated({ segment: ["a", "b", "c"] }); //=> "/a/b/c"

const toPathRegexp = compile("/user/:id(\\d+)");

toPathRegexp({ id: 123 }); //=> "/user/123"
toPathRegexp({ id: "123" }); //=> "/user/123"

Note: The generated function will throw on invalid input.

Working with Tokens

Path-To-RegExp exposes the two functions used internally that accept an array of tokens:

  • tokensToRegexp(tokens, keys?, options?) Transform an array of tokens into a matching regular expression.
  • tokensToFunction(tokens) Transform an array of tokens into a path generator function.

Token Information

  • name The name of the token (string for named or number for unnamed index)
  • prefix The prefix string for the segment (e.g. "/")
  • suffix The suffix string for the segment (e.g. "")
  • pattern The RegExp used to match this token (string)
  • modifier The modifier character used for the segment (e.g. ?)

Compatibility with Express <= 4.x

Path-To-RegExp breaks compatibility with Express <= 4.x:

  • RegExp special characters can only be used in a parameter
    • Express.js 4.x supported RegExp special characters regardless of position - this is considered a bug
  • Parameters have suffixes that augment meaning - *, + and ?. E.g. /:user*
  • No wildcard asterisk (*) - use parameters instead ((.*) or :splat*)

Live Demo

You can see a live demo of this library in use at express-route-tester.

License

MIT

path-to-regexp's People

Contributors

aredridel avatar blakeembrey avatar boringame avatar chadkillingsworth avatar damianku avatar feimosi avatar fidian avatar forbeslindesay avatar frenzzy avatar glebsts avatar guria avatar helloyou2012 avatar iamandrewluca avatar inigomarquinez avatar izaakschroeder avatar janpot avatar jonathanong avatar jonchurch avatar kettanaito avatar lijunle avatar mcfung avatar ndelvalle avatar nook-scheel avatar pinksynth avatar ryanwalters avatar segmentational avatar tj avatar topeomot2 avatar vanodevium avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

path-to-regexp's Issues

Example using old code

The example (Live Demo) on the Readme.md file is using the old express code. It doesn't reflect exactly what this module does.

An example of this is if you use /path/* pattern it will match /path/more/deep, while path-to-regexp generated regex won't.

broke for me :(

> path('/:remote([\\w-.]+)')
/^\/([\w-.]+)\/?$/i
> path('/:remote([\\w-.]+)/:user([\\w-]+)')
/^\/([\w-.]+\)\/\:user\([\w-]+)\/?$/i

why is there a :user there?

support question - can't figure out how to use this correctly

I simply want to test if a given route, via req.path in Express, matches a regex compiled by this library

so if I have this Express style regex path: var x = '/user/:id/foo'

I am guessing (but appear to be wrong) that the way to do this would be:

var regex = pathToRegexp.compile(x);

then in real life, I get an actualy url path, such as var p = '/user/123/foo'

so I want to test if the above regex matches p

so that would be regex.test(p);

but this doesn't seem to be working, is my approach backwards?

thanks!

publish to npm?

It seems the npm package is still the deprecated component/path-to-regexp. Ideally we should have npm point to this package instead. What npm username do I need to add for publishing to be possible? Cheers!

Invalid passiv group

string 'bitrix/components/bss/carousel/templates/main/assets/stylesheets/styles.less'

var regPath = regexpPath('bitrix/:type/(?:bss|bitrix-ripe/components/bss)/:component/templates/:template/(.*)');

Problem in excess '' -> (?:bss|

SyntaxError: Invalid regular expression: /^bitrix\/([^\\/]+?)\/(?\:bss|bitrix-ripe\/components\/bss)\/([^\\/]+?)\/templates\/([^\\/]+?)\/(.*)(?:\/(?=$))?$/: Invalid group

"/:path(abc|xyz)*" doesn't produce the expected result.

node -pe 'require("path-to-regexp")("/:path(abc|xyz)*")'
{ /^(?:\/(abc|xyz(?:\/abc|xyz)*))?(?:\/(?=$))?$/i
  keys: 
   [ { name: 'path',
       prefix: '/',
       delimiter: '/',
       optional: true,
       repeat: true,
       pattern: 'abc|xyz' } ] }

The generated expression unexpectedly matches /xyz/abc, but not /abc/xyz.

Release to npm

Could you do a new release to npm for that latest fix.

How to use newer versions with express?

Express 4.13.3 seems to depend on old path-to-regexp version 0.1.7
A lot of cool things that work in the express route tester turn out to not actually work in express, and I assume it is because of the version difference.
Is there a recommended way to get express to use the new versions, or should I just hack its package.json, or what?

Make trailing slash optional in splat params.

Hey,

I often find myself writing paths like this:

app.get('/test/*', ...)

// Which becomes

app.get('/test/(.*)', ...)

However 100% of the time what I actually want is this:

app.get('/test(/?.*)', ...)

Is it possible to make a splat only section of the path allow for optional trailing slash?

I realize this would be a breaking change, but I can't perceive any crazy issues with it and it would be pretty convenient for myself and perhaps others.

Please add LICENSE file

Hi,

please add a LICENSE file which includes a full text of MIT license. This is really important to distribute your work.

Impossible to compile to + and *

var toPath = pathToRegexp.compile('/goods/:splat+')
var result = toPath({ splat: '1/all' })  //error

var toPath = pathToRegexp.compile('/goods/:splat(.+)')
var result = toPath({ splat: '1/all' })
console.log(result) //=> "/goods/1%2Fall"

Add keys as a prop on RegExp?

Since this module returns a RegExp object and already formed the capture groups, wouldn't it be awesome if added a property with the list of capture names instead of doing a weird out-variable deal?

index b2a5755..9e20f9d 100644
--- a/index.js
+++ b/index.js
@@ -51,5 +51,7 @@ function pathtoRegexp(path, keys, options) {
     })
     .replace(/\*/g, '(.*)');

-  return new RegExp('^' + path + (end ? '$' : '(?=\/|$)'), sensitive ? '' : 'i');
+  var re = new RegExp('^' + path + (end ? '$' : '(?=\/|$)'), sensitive ? '' : 'i');
+  re.keys = keys;
+  return re;
 };

Partial matches

How do you tell path-to-regexp not to add a $ to the end of your regexp?

Patterns with capturing group(s) spanning over "/" are not compilable

Patterns like asterisk matches multiple path parts delimited by "/", however they are not considered as repeatable, so they capture a single string containing "/" characters.
If you provide such string as a prameter to the pathToRegexp.compile function, the "/" character is escaped, resulting in a different url.

var re = pathToRegexp('/assets/*');
re.exec("/assets/a/b/c/d");
// [ '/assets/a/b/c/d', 'a/b/c/d', index: 0, input: '/assets/a/b/c/d' ]
var toPath = pathToRegexp.compile('/assets/*')
toPath({"0": "a/b/c/d"}); // also tried with { pretty: true }
// /assets/a%2Fb%2Fc%2Fd

Regex Syntax

I'm using koa-controller.

Trying to get this to work, I've tried several variations of syntax here:

'/countries/:countryUrlFriendlyName(/^[a-z-]+$/i)/states/:stateUrlFriendlyName(/^[a-z-]+$/i)/cities/:cityUrlFriendlyName(/^[a-z-]+$/i)': {to: 'city#findByCountryAndStateAndCityUrlFriendlyName'}

'/countries/:(/^[a-z-]+$/i)/states/:(/^[a-z-]+$/i)/cities/:(/^[a-z-]+$/i)': {to: 'city#findByCountryAndStateAndCityUrlFriendlyName'}

'/countries/(/^[a-z-]+$/i)/states/(/^[a-z-]+$/i)/cities/(/^[a-z-]+$/i)': {to: 'city#findByCountryAndStateAndCityUrlFriendlyName'}

I want to be able to allow any characters including if they have dashes between them. For example I want to allow these types of urls incoming to the router:

/countries/united-states-of-america/states/illinois/cities/chicago
/countries/unitedstatesofamerica/states/illinois/cities/chicago

no luck so far, I'm sure I'm just missing something here..what is it?

Maybe readme doc is not correct

About the second parameter keys, it says Once the function completes, this will be an array of strings.. Isn't it an array of objects which looks like {name: xxx, optional: !!optional}?

Bower package?

Could we get a bower package for this repo? I tried git://github.com/pillarjs/path-to-regexp.git#1.3.0 but get "ENOTFOUND Package juliangruber/isarray=juliangruber/isarray not found".
Thanks!

query parameters and RegExp's involving path parameter

I encountered an inconsistency when constructing RegExp's for paths involving path parameters. Here is an example:

var matcher = pathToRegexp('/fetch');   // /^\/fetch(?:\/(?=$))?$/i
var a = '/fetch';
var b = '/fetch/';
var c = '/fetch?foo=bar';
var d = '/fetch/?foo=bar';

Strings a and b match against the regex, and both c and d do not. This matches my expectation that pathToRegexp is not meant to manage query parameter parsing without additional code.

var matcher = pathToRegexp('/fetch/:id');   // /^\/fetch\/((?:[^\/]+?))(?:\/(?=$))?$/i
var a = '/fetch/1';
var b = '/fetch/1/';
var c = '/fetch/1?foo=bar';
var d = '/fetch/1/?foo=bar';

Strings a, b, and c will all match against the regex, but d will not. I would expect c and d to both fail to match given the behavior in the previous example. The trailing / makes the difference: regexp visualization. The capture group intended to match the path param ends up also matching against the query with string c.

Is the issue here just that pathToRegexp is not designed to analyze request url's that have not had their query portion removed? Should I clean the query first?

trailing capture

would be nice to capture everything in the tail into the last capture group:

route('/:user/:project/:version/:file...')

or something. file should then include the entire file name including all the /s. * doesn't exactly work how i'd like. we could then base mounting off of this or something.

Bug with index property and arrays in 0.1.5

Hi! It looks like there is a bug in the new index feature of 0.1.5 when given arrays:

$ node -pe 'require("path-to-regexp/package").version'
0.1.5

$ node -pe 'var k=[],r=require("path-to-regexp")(["/user/:user/poke","/user/:user/pokes"],k);k'
[ { name: 'user', optional: false, index: 0, _offset: 7 },
  { name: 'user', optional: false, index: 0, _offset: 7 } ]

As you can see in the output above, both entries are marked as index = 0, when one of them should actually be index = 1.

Path wildcards

I was using pathRegexp() from from Express utils, but since this was removed in 4, I had to migrate to path-to-regexp. I was using it to match an URL only (to get the context for a page) not actually using parameters.

The problem is that /some-path/* URLs stopped working and I need to change it across all the application to use /some-path/(.*).

Since this is an application to be used also by non programmers, /some-path/* would be more straightforward.

Do you have any plans to bring back /some-path/* at some point?

Unicode Character Expansion

I'm opening this issue to create a conversation around supporting unicode and other illegal characters in the path string. For example, matching 我 currently requires using %E6%88%91 as part of the path in the current version of the module. Any thoughts?

Regex with starting optional group after forward slash gives error

I'm using express which uses path-to-regexp for URL routing.

If I use the following regex:

'/(apple-)?icon-:res(\\d+)x\\2.png'

I get the following error:

Invalid regular expression: /^\/(?(?:([^\/]+?))-)?icon-(?:(\d+))x\2\.png\/?$/: Invalid group

Using escaped forward slash still gives an Invalid group error

Breaking it down to just

'/(apple-)?'

gives

/^\/(?(?:([^\/]+?))-)?\/?$/: Invalid group

My current workaround is to do the following:

'/?(apple-)?icon-:res(\\d+)x\\2.png'

`npm test` fails on Windows

Due to gotwarlost/istanbul#13, npm test flat out fails on Windows:

C:\git\path-to-regexp>npm test

> [email protected] test C:\git\path-to-regexp
> istanbul cover _mocha -- -R spec


C:\git\path-to-regexp\node_modules\.bin\_mocha.CMD:1
(function (exports, require, module, __filename, __dirname) { @IF EXIST "%~dp0
                                                              ^
No coverage information was collected, exit without writing coverage information
SyntaxError: Unexpected token ILLEGAL
    at Module._compile (module.js:439:25)
    at Module._extensions..js (module.js:474:10)
    at Object.Module._extensions..js (C:\git\path-to-regexp\node_modules\istanbul\lib\hook.js:101:13)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at runFn (C:\git\path-to-regexp\node_modules\istanbul\lib\command\common\run-with-cover.js:113:16)
    at C:\git\path-to-regexp\node_modules\istanbul\lib\command\common\run-with-cover.js:223:17
    at C:\git\path-to-regexp\node_modules\istanbul\lib\util\file-matcher.js:52:16
    at C:\git\path-to-regexp\node_modules\istanbul\lib\util\file-matcher.js:35:9
npm ERR! Test failed.  See above for more details.
npm ERR! not ok code 0

tokensToRegexp keys

Currently there is no way (that I know of) to populate a keys array using tokensToRegexp.
I'm not sure why this is, would it be possible to add? (or expose the attachKeys function).


Edit

I guess technically you can just manually set keys on the returned tokens.
Going to keep this open to hear your thoughts on it though.

Named predefined params

Original issue: expressjs/express#2127

Using this code from doc

app.param (name, regexp) ->
    if Object.prototype.toString.call(regexp) == '[object RegExp]'
        return (req, res, next, val) ->
            if captures = regexp.exec(String(val))
                req.params[name] = captures[0]
                next()
            else
                next('route')

I can use named params with regex match, but I can't use this param more than 1 time and generic names make the url a little messy.

I can't do this

app.get '/purchase/:objectId/:objectId', (req, res, next) ->

There are some way to name this params like below?

app.get '/purchase/:(objectId)place/:(objectId)user', (req, res, next) ->
    console.log req.params.place, req.params.user

Typed parameters in routes

As mentioned in expressjs/express#2756, it would be nice to have

app.route('/:an_id{number}');
app.route('/:another_id{string}')

and an_id to actually be a number instead of string.

I implemented something here afebe50, but I would like to ask for feedback, and if this is something that is desirable.

I think the way I put the typedMatch function on the regexp object is not quite nice, so I'd like to hear some feedback.

Also I know it lacks documentation in the README but that should come when and if this is something desirable.

it seems Unnamed Parameters don't work

var pathToRegexp = require('path-to-regexp')
var keys = []
var re = pathToRegexp('/:foo/(.*)', keys);

keys
[ { name: 'foo', optional: false } ]

keys only have name parameters

Match extension when strict mode false

In Express, when setting a middle where like:

app.use("/some/path" ... );

It will not match "/some/path.json" even though the call to path-to-regexp is not using strict. It will allow you to use "/some/path/json" however.

The only way I could find to fix this is by changing the regex in this line to be like (?=[\\/\\.]|$) instead of (?=\\/|$). That code causes a few tests to fail though.

I can make a Pull Request if needed.

host-to-regexp

Is there any consideration to allow path-to-regexp to support generating host matching regexes? As far as I can tell all that would change is that the delimiter in the regs would go from / to ..

This would be pretty handy for node servers handling multiple domains/subdomains.

Typings file not published with npm

The typings file in the repository isn't published in npm, as far as I could tell. Also, the only typings found elsewhere are the tsd typings for the deprecated path-to-regexp.

help: Handling parentheses in the path pattern not related prefixes

I currently use path-to-regexp in Sway and a user reported an issue that I believe will require me to do a little escaping prior to calling path-to-regexp. The user is currently trying to create an OData path like /Users(:id) but a request path of /Users(1) does not match the regex where I would expect it to. Now, I realize the reason for this is that parentheses are special but before I just go blindly escaping/hacking this to work, I wanted to get your opinion on how best to handle this situation.

Note: OpenAPI/Swagger use bracket-based variable naming in paths so in the linked issue you'll see /Users({id}) instead of /Users(:id). Do not let this trip you up because I already handle converting OpenAPI/Swagger paths to Express-style paths. Also, OpenAPI/Swagger paths do not allow regex in their path pattern (in case that matters with suggesting a solution).

Wildcard with exceptions

Hey! I'd love a way to use negative lookahead regexes in my paths, for example *(?!foo) to match everything but 'foo'.

However, this does not work. Output:
'Uncaught SyntaxError: Invalid regular expression: /^/:((?:?!foo))(?:/(?=$))?$/: Nothing to repeat'

Maybe there's already a way to do this that I don't know of?

Support sub patterns for parameters

When I was using the Play framework, they had the ability to specify subpatterns for named parameters using a syntax such as:

/clients/{<[0-9]+>id}

Here, the named parameter was id and it would only match against numbers.

I'd really like to see the ability to do subpattern matching such as this make it into express. Maybe something like:

/clients/:id(\d+)

I'm happy to submit a patch if this enhancement will be considered.

regex starting with parenthesis gets interpreted incorrectly

I'm using an express app in this context and it seems that the issue comes down to this module. I'm using [email protected] which uses [email protected]. I noticed that the current release for this module is 1.7.0, however.

The following route is something I'm trying to get my app to use:

router.use('/(segment1|segment2|segment3)', someMethod);

Logically, I would expect the following routes to be visible to the app now:

  • host.com/segment1
  • host.com/segment2
  • host.com/segment3

However, the app is unable to run at all which throws the following error:

SyntaxError: Invalid regular expression: /^\/(?(?:([^\/]+?))|segment2|segment3)\/?(?=\/|$)/: Invalid group

Notice how segment1 is entirely ignored but changed into some other random regexp? The error is pointing to the underlying library of at pathtoRegexp (...node_modules/path-to-regexp/index.js:128:10) so i'm not sure if it's an issue with that module or if express is doing something to that route before it gets passed to that module.

This is the entire stack trace after my app tries to spin up:

SyntaxError: Invalid regular expression: /^\/(?(?:([^\/]+?))|jewelry|fashion|art)\/?(?=\/|$)/: Invalid group
    at RegExp (native)
    at pathtoRegexp (/site/node_modules/path-to-regexp/index.js:128:10)
    at new Layer (/site/node_modules/express/lib/router/layer.js:45:17)
    at Function.use (/site/node_modules/express/lib/router/index.js:464:17)
    at Object.<anonymous> (index.es.js:38:8)

the index.es.js reference is where the router.use method kicks off.

patterns with once or more `+` is broken

version 1.4.0

> p = require('path-to-regexp')
{ [Function: pathToRegexp]
  parse: [Function: parse],
  compile: [Function: compile],
  tokensToFunction: [Function: tokensToFunction],
  tokensToRegExp: [Function: tokensToRegExp] }
> p('/:foo+').exec('/foo/bar')
[ '/foo/bar', 'foo/bar', index: 0, input: '/foo/bar' ]
> p('/:foo+baz').exec('/foo/barbaz')
null
> p('/:foo+')
{ /^\/((?:[^\/]+?)(?:\/(?:[^\/]+?))*)(?:\/(?=$))?$/i
  keys:
   [ { name: 'foo',
       prefix: '/',
       delimiter: '/',
       optional: false,
       repeat: true,
       pattern: '[^\\/]+?' } ] }
> p('/:foo+baz')
{ /^\/((?:[^\/]+?)(?:(?:[^\/]+?))*)baz(?:\/(?=$))?$/i
  keys:
   [ { name: 'foo',
       prefix: '',
       delimiter: '/',
       optional: false,
       repeat: true,
       pattern: '[^\\/]+?' } ] }
>

p('/:foo+baz') should results /^/((?:[^\/]+?)(?:\/(?:[^\/]+?))*)baz(?:/(?=$))?$/i
the \/ is missing

Parentheses within custom match regexp

I'd like to be able to define groups within my custom match regexp like so:
/:foo(\\d+(\\.\\d+)?)

Which I would expect to match both of these paths:
/123
/123.123

Currently this doesn't seem to work as it appears to be parsing the inner parentheses as a new key. Any ideas on how I could achieve something like this?

My workaround for the moment is to define two separate paths like /:foo(\\d+) and /:foo(\\d+\\.\\d+), but I'd love to just have one like I defined above.

Ability to convert tokens to regex.

The #parse method returns an array of tokens, it would be cool if we could pass in those tokens to get a regex again.

It would be useful to merge multiple parsed paths.

I could do a PR if anyone else things this is a good idea.

Release v1.0.0

We should try and move this module to a stable 1.0.0 release as soon as possible.

Perhaps going through and quickly closing out all the outstanding issues first? Ideally we should make this pretty much locked (see http://nodejs.org/api/documentation.html) soon.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.