easier than regex string matching patterns for urls and other strings. turn strings into data or data into strings.

Related tags

String url-pattern
Overview

url-pattern

NPM Package Build Status Sauce Test Status codecov.io Downloads per Month

easier than regex string matching patterns for urls and other strings.
turn strings into data or data into strings.

This is a great little library -- thanks!
michael

make pattern:

var pattern = new UrlPattern('/api/users(/:id)');

match pattern against string and extract values:

pattern.match('/api/users/10'); // {id: '10'}
pattern.match('/api/users'); // {}
pattern.match('/api/products/5'); // null

generate string from pattern and values:

pattern.stringify() // '/api/users'
pattern.stringify({id: 20}) // '/api/users/20'

check out passage if you are looking for simple composable routing that builds on top of url-pattern

npm install url-pattern
bower install url-pattern
> var UrlPattern = require('url-pattern');
> var pattern = new UrlPattern('/v:major(.:minor)/*');

> pattern.match('/v1.2/');
{major: '1', minor: '2', _: ''}

> pattern.match('/v2/users');
{major: '2', _: 'users'}

> pattern.match('/v/');
null
> var pattern = new UrlPattern('(http(s)\\://)(:subdomain.):domain.:tld(\\::port)(/*)')

> pattern.match('google.de');
{domain: 'google', tld: 'de'}

> pattern.match('https://www.google.com');
{subdomain: 'www', domain: 'google', tld: 'com'}

> pattern.match('http://mail.google.com/mail');
{subdomain: 'mail', domain: 'google', tld: 'com', _: 'mail'}

> pattern.match('http://mail.google.com:80/mail');
{subdomain: 'mail', domain: 'google', tld: 'com', port: '80', _: 'mail'}

> pattern.match('google');
null

make pattern from string

> var pattern = new UrlPattern('/api/users/:id');

a pattern is immutable after construction.
none of its methods changes its state.
that makes it easier to reason about.

match pattern against string

match returns the extracted segments:

> pattern.match('/api/users/10');
{id: '10'}

or null if there was no match:

> pattern.match('/api/products/5');
null

patterns are compiled into regexes which makes .match() superfast.

named segments

:id (in the example above) is a named segment:

a named segment starts with : followed by the name.
the name must be at least one character in the regex character set a-zA-Z0-9.

when matching, a named segment consumes all characters in the regex character set a-zA-Z0-9-_~ %. a named segment match stops at /, ., ... but not at _, -, , %...

you can change these character sets. click here to see how.

if a named segment name occurs more than once in the pattern string, then the multiple results are stored in an array on the returned object:

> var pattern = new UrlPattern('/api/users/:ids/posts/:ids');
> pattern.match('/api/users/10/posts/5');
{ids: ['10', '5']}

optional segments, wildcards and escaping

to make part of a pattern optional just wrap it in ( and ):

> var pattern = new UrlPattern(
  '(http(s)\\://)(:subdomain.):domain.:tld(/*)'
);

note that \\ escapes the : in http(s)\\://. you can use \\ to escape (, ), : and * which have special meaning within url-pattern.

optional named segments are stored in the corresponding property only if they are present in the source string:

> pattern.match('google.de');
{domain: 'google', tld: 'de'}
> pattern.match('https://www.google.com');
{subdomain: 'www', domain: 'google', tld: 'com'}

* in patterns are wildcards and match anything. wildcard matches are collected in the _ property:

> pattern.match('http://mail.google.com/mail');
{subdomain: 'mail', domain: 'google', tld: 'com', _: 'mail'}

if there is only one wildcard then _ contains the matching string. otherwise _ contains an array of matching strings.

look at the tests for additional examples of .match

make pattern from regex

> var pattern = new UrlPattern(/^\/api\/(.*)$/);

if the pattern was created from a regex an array of the captured groups is returned on a match:

> pattern.match('/api/users');
['users']

> pattern.match('/apiii/test');
null

when making a pattern from a regex you can pass an array of keys as the second argument. returns objects on match with each key mapped to a captured value:

> var pattern = new UrlPattern(
  /^\/api\/([^\/]+)(?:\/(\d+))?$/,
  ['resource', 'id']
);

> pattern.match('/api/users');
{resource: 'users'}

> pattern.match('/api/users/5');
{resource: 'users', id: '5'}

> pattern.match('/api/users/foo');
null

stringify patterns

> var pattern = new UrlPattern('/api/users/:id');

> pattern.stringify({id: 10})
'/api/users/10'

optional segments are only included in the output if they contain named segments and/or wildcards and values for those are provided:

> var pattern = new UrlPattern('/api/users(/:id)');

> pattern.stringify()
'/api/users'

> pattern.stringify({id: 10})
'/api/users/10'

wildcards (key = _), deeply nested optional groups and multiple value arrays should stringify as expected.

an error is thrown if a value that is not in an optional group is not provided.

an error is thrown if an optional segment contains multiple params and not all of them are provided. one provided value for an optional segment makes all values in that optional segment required.

look at the tests for additional examples of .stringify

customize the pattern syntax

finally we can completely change pattern-parsing and regex-compilation to suit our needs:

> var options = {};

let's change the char used for escaping (default \\):

> options.escapeChar = '!';

let's change the char used to start a named segment (default :):

> options.segmentNameStartChar = '$';

let's change the set of chars allowed in named segment names (default a-zA-Z0-9) to also include _ and -:

> options.segmentNameCharset = 'a-zA-Z0-9_-';

let's change the set of chars allowed in named segment values (default a-zA-Z0-9-_~ %) to not allow non-alphanumeric chars:

> options.segmentValueCharset = 'a-zA-Z0-9';

let's change the chars used to surround an optional segment (default ( and )):

> options.optionalSegmentStartChar = '[';
> options.optionalSegmentEndChar = ']';

let's change the char used to denote a wildcard (default *):

> options.wildcardChar = '?';

pass options as the second argument to the constructor:

> var pattern = new UrlPattern(
  '[http[s]!://][$sub_domain.]$domain.$toplevel-domain[/?]',
  options
);

then match:

> pattern.match('http://mail.google.com/mail');
{
  sub_domain: 'mail',
  domain: 'google',
  'toplevel-domain': 'com',
  _: 'mail'
}

frequently asked questions

how do i match the query part of an URL ?

the query part of an URL has very different semantics than the rest. url-pattern is not well suited for parsing the query part.

there are good existing libraries for parsing the query part of an URL. https://github.com/hapijs/qs is an example. in the interest of keeping things simple and focused i see no reason to add special support for parsing the query part to url-pattern.

i recommend splitting the URL at ?, using url-pattern to parse the first part (scheme, host, port, path) and using https://github.com/hapijs/qs to parse the last part (query).

how do i match an IP ?

you can't exactly match IPs with url-pattern so you have to fall back to regexes and pass in a regex object.

here's how you do it

contributing

license: MIT

Comments
  • Not only parse, also generate

    Not only parse, also generate

    So basically what your library does is extracting some data structure from url based on certain pattern. Can you please implement the opposite thing. I mean some method to which you feed data structure and get url string in return.

    Something like

    var pattern = new UrlPattern('/posts/:start/:count/:whatever');
    assert(pattern.generate({
      start: 1,
      count: 100,
      whatever: 'whatever'
    }) === '/posts/1/100/whatever');
    

    Such feature would allow (me) to write routers together with History API manipulation in browser quite easily.

    implementation-complete 
    opened by mixtur 18
  • Couldn't match this pattern

    Couldn't match this pattern "/v:major.:minor/*"

    I'm trying to match the api version number from the url like this:

    UrlPattern = require 'url-pattern'
    pattern = UrlPattern.newPattern '/v:major.:minor/*'
    result = pattern.match(req.path)
    console.log result
    

    When I use this url /v1.1/resource/?token=1234567890 it gives me:

    { 'major.:minor': '1.1', _: [ 'resource/' ] }
    

    but I'm trying to match the :major & :minor version numbers!

    opened by Abdelhady 8
  • Store * match in _ attribute.

    Store * match in _ attribute.

    Hi, I use your library in https://github.com/andreypopp/react-router-component with a great success. For a new feature called "contextual routers" (a way to define nested routers hierarchies) I need to store a result of * matches.

    This PR implements the needed change. What do you think about this?

    opened by andreypopp 5
  • Support for embedded urls as query parameters possible?

    Support for embedded urls as query parameters possible?

    Hey,

    First of all love the library. Got 90% of the way through my implementation of a URL matching algorithm with url-pattern as the backbone but hit a snag on an edge-case unfortunately.

    Is there any way to cleanly support urls that have urls as query parameters?

    Example: https://translate.google.com/translate?sl=auto&tl=es&u=yahoo.com

    It seems to cause a hiccup in the code.

    const pattern = new urlPattern('https://translate.google.com/translate?sl=auto&tl=es&u=yahoo.com');

    ->

    Error: could only partially parse pattern
        at new UrlPattern (/home/runner/node_modules/url-pattern/lib/url-pattern.js:391:13)
        at evalmachine.<anonymous>:50:17
        at Script.runInContext (vm.js:107:20)
        at Object.runInContext (vm.js:285:6)
        at evaluate (/run_dir/repl.js:133:14)
        at ReadStream.<anonymous> (/run_dir/repl.js:116:5)
        at ReadStream.emit (events.js:189:13)
        at addChunk (_stream_readable.js:284:12)
        at readableAddChunk (_stream_readable.js:265:11)
        at ReadStream.Readable.push (_stream_readable.js:220:10)   
    

    Any ideas?

    opened by seantcanavan 4
  • Require one of a few possible values?

    Require one of a few possible values?

    Is is possible to match something like this, all in one URLPattern?

    a/(b|c|d)/:var
    

    In short, the path must contain exactly one of b, c, or d before the variable portion of the path. I read over the docs / test cases and didn't see anything like this, but apologies if I missed it!

    opened by jkillian 4
  • Unlimited subdomains?

    Unlimited subdomains?

    Hi,

    i can't see to find how i can achieve matching an unlimited number of sub domains.

    i did something like new UrlPattern("((:protocol)\\://)((((((:subdomain.):subdomain.):subdomain.):subdomain.):subdomain.):domain.)(:tld)(\\:(:port))(/*)")

    hoping there would not be more than 5 but it appears that my application encounters links with more than 5. I could write for 6 or 7 or 8 but that wouldn't do me much good.

    I was looking for a ([:subdomain\.]?) regex syntax like format.

    Thanks

    opened by vaiulian 4
  • url-pattern does treats fullstops in urls different to express.

    url-pattern does treats fullstops in urls different to express.

    The URL /api/v1/user/test.name/ would be captured by the expressjs route /api/v1/user/:id/ but is not captured by the url-pattern /api/v1/user/:id/.

    The resulting regex should include the full stop as a valid char. \/api\/v1\/user\/([a-zA-Z0-9-_ % \.]+)\/

    opened by thepont 4
  • How to match encoded URI?

    How to match encoded URI?

    I have this Pattern:

    const template = '/members/:userId'
    const pattern = new UrlPattern(template);
    const match = pattern.match(url);
    

    if my url looks like this /members/user%40example.org I don't get a match.

    opened by AlexZeitler 3
  • Provided typings do not work for TS2

    Provided typings do not work for TS2

    On TS 2.0.10, attempting to use UrlPattern like this:

    import { UrlPattern } from 'url-pattern';

    This fails with error: .........node_modules/url-pattern/index"' has no exported member 'UrlPattern'.

    Do you only support a particular TS version?

    opened by ghost 3
  • `pattern.match` does not match wildcard paths appropriately if missing trailing slash

    `pattern.match` does not match wildcard paths appropriately if missing trailing slash

    If we have a route, such as /snd/url-pattern and we do not have a trailing forward slash (in other words, if the route is not /snd/url-pattern/ with the trailing /), then it does not match the wildcard path of /snd/url-pattern/* as it should. Here is a code snippet:

    var UrlPattern = require('url-pattern');
    var pattern = new UrlPattern('/snd/url-pattern/*');
    console.log(pattern.match('/snd/url-pattern')); // returns `null`
    

    The only possible idea I have right now to fix this is to use this middleware in order to automatically 301 redirect to trailing slashes https://github.com/avinoamr/connect-slashes.

    Do you think you can fix this in your package, or is there a more appropriate way for me to do this?

    opened by niftylettuce 3
  • matching `~`

    matching `~`

    I know I can change compiler.segmentValueCharset to do that. Just wondering why don't you support all the unreserved characters in RFC3986 (without .) by default. Is there any special meaning for ~ in some use cases?

    implementation-complete 
    opened by caasi 3
  • Using OR conditions

    Using OR conditions

    Hi! I tried to use "/feed|/rss" pattern to match URLs like /feed and /rss but it doesn't work as expected. Maybe I'm using wrong syntax for OR conditions, I didn't find the correct way in the documentation.

    opened by vvotekeb 0
  • i'd like to be able to access the url options as an exposed type / interface

    i'd like to be able to access the url options as an exposed type / interface

    hi! first of all, thanks for giving us this cool library.

    i'm using it in one of my typescript projects and i want to access the definitions for url options.

    i'm thinking of doing it by reworking the definitions file a little, adding a namespace to expose what i need. Something like this, perhaps.

    i believe this approach wouldn't cause breaking changes. Would like to hear your thoughts on this please. TIA!

    image

    opened by iamkenos 0
  • how to create pattern for unlimited amount of url parameters?

    how to create pattern for unlimited amount of url parameters?

    It's probably on me, but I was unable to create a pattern for url's like this:

    <url>/present/tag1/tag2/tag3/[...tagN]
    

    the <url>/present is a const, the tags are coming at the end of it.

    This is what Ive been trying with:

    new UrlPattern(/^\/present\/(.*)$/);
    

    but then result is:

    ["1-lorem/5-ipsum"]
    

    which is an array, with a single item.

    Now i could split it by / but then the usage of url-pattern becomes quite unnecessary, so I'd rather solve it using the corerct way.

    What i am aiming for is something like this:

    ["1-lorem", "2-ipsum"]
    

    Any help is appreciated.

    opened by zilahir 0
  • Named regex segments?

    Named regex segments?

    var UrlPattern = require("url-pattern")

    Is there any way to enforce regex at a segment level?

    I have a pattern for username with a @.

    The current route matchers are failing with the @.

      var pattern = new UrlPattern(':username/:postID');
      pattern.match('@stoplion/123');
    

    I think I can build the regex like this..

       var pattern = new UrlPattern(/@[a-z0-9][-a-z0-9]+)\/([a-z0-9][-a-z0-9]+)/, ['username', 'postIid']);
    

    The URL itself is very hard to read, and I can't figure out what it is at a glance..

    Is it possible to do something like this.. Where you can get the named segments, and then enforce a regex pattern

    var pattern = new UrlPattern(':username/:postID', {
       username: /@[a-z0-9][-a-z0-9]+/
    });
    
    opened by stoplion 0
  • when run into different context,this judge will be wrong.

    when run into different context,this judge will be wrong.

    A case:

    <script>
    let testVal = new window.inner.contentWindow.RegExp(/testReg/);
    console.log(testVal instanceof RegExp);//false
    </script>
    
    <iframe id="inner"></iframe>
    
    opened by wednesday 0
Owner
null
String manipulation helpers for javascript

The stable release documentation can be found here https://epeli.github.io/underscore.string/ Underscore.string Javascript lacks complete string manip

Esa-Matti Suuronen 3.4k Dec 25, 2022
Extra JavaScript string methods.

string.js string.js, or simply S is a lightweight (< 5 kb minified and gzipped) JavaScript library for the browser or for Node.js that provides extra

JP Richardson 1.8k Dec 17, 2022
Lo-fi, powerful, community-driven string manipulation library.

Lo-fi, powerful, community-driven string manipulation library. This is the main monorepo codebase of Plexis.js a production-ready string manipulation

Plexis 145 Sep 24, 2022
Parse and stringify URL query strings

query-string Parse and stringify URL query strings My open source work is supported by the community Special thanks to: All your environment variables

Sindre Sorhus 6.2k Jan 9, 2023
Multiline strings in JavaScript

multiline Multiline strings in JavaScript No more string concatenation or array join! Use ES2015 template literals instead whenever possible. Before c

Sindre Sorhus 1.4k Dec 30, 2022
microregex is an open source and highly curated catalog of regular expression patterns. It offers programmers RegEx snippets that can be quickly exported into a variety of programming languages and distributed around teams.

microregex - A catalog of RegEx patterns View Demo · Report Bug · Request Feature Loved the tool? Please consider contributing ✍️ to help it improve!

Sunit Shirke 4 Oct 25, 2022
Helps to encode a string to base64 and decode a base64 string to a normal string.

@prashoonb/base64-encoder-decoder Installation npm install @prashoonb/base64-encoder-decoder API base64.encode(input) This function takes a byte strin

PrashoonB 4 Mar 29, 2022
Convert some JavaScript/TypeScript code string into a .d.ts TypeScript Declaration code string

convert-to-dts Converts the source code for any .js or .ts file into the equivalent .d.ts code TypeScript would generate. Usage import { convertToDecl

Lily Scott 11 Mar 3, 2022
Transform URLs in strings to actual links.

Transform URLs in strings to actual links. It will find valid links in the given string and create <a> tags for it. Internally, it uses this Regex to

Prince Neil Cedrick Castro 7 Nov 4, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
This package is for developers to be able to easily integrate bad word checking into their projects.\r This package can return bad words in array or regular expression (regex) form.

Vietnamese Bad Words This package is for developers to be able to easily integrate bad word checking into their projects. This package can return bad

Nguyễn Quang Sáng 8 Nov 3, 2022
✏️ A small jQuery extension to turn a static HTML table into an editable one. For quickly populating a small table with JSON data, letting the user modify it with validation, and then getting JSON data back out.

jquery-editable-table A small jQuery extension to turn an HTML table editable for fast data entry and validation Demo ?? https://jsfiddle.net/torrobin

Tor 7 Jul 31, 2022
A script that implements a GUI to make cheating on Blooket easier than ever.

BlooketUI What's BlooketUI? A script that implements a GUI to make cheating on Blooket easier than ever. How do i Use This? Copy the code of src.js by

null 66 Dec 24, 2022
Useful userscript, allowing you to steal NFTs from Twitter even easier than before!

Adds missing feature that even Twitter Blue doesn't have: click on hexagonal avatar to open it in a new tab and save yourself a couple of clicks while stealing it!

Andrey Viktorov 4 Jan 21, 2022
Sharing short code samples, logs or links is now easier than ever!

Pastebin Sharing short code samples, logs or links is now easier than ever. Explore the docs » • Report Bug • Request Feature • About The Project With

Prasoon Soni 4 Nov 26, 2022
Simple string diffing. Given two strings, striff will return an object noting which characters were added or removed, and at which indices

Simple string diffing. Given two strings, striff will return an object noting which characters were added or removed, and at which indices

Alex MacArthur 196 Jan 6, 2023
A chainable router designed for Next.js api. inspired and regex based from itty-router

Next.js Api Router A chainable router designed for Next.js api. inspired and regex based from itty-router Features Tiny (~8xx bytes compressed) with z

Aris Riswanto 1 Jan 21, 2022