Search code examples
javascriptpythonhtmlregexweb

matching regex for custom params in URI


I am building a web framework and REGEX is really hostile today. I do not like the django way of formatting custom params with angle brackets

url/<param>/... or
<str:token>/

I would prefer the way js and other programs handle this

name/:token/:another_param

After trying for 45 minutes I am giving up. I would like to allow only characters like a-zA-Z0-9_:/. The main issue here is that I do not want to allow recursive colons like this

:::id

These are strings I would like to match

empty string (although I could check prior matching)
/
:id
/:id
/:id/
person/:name/:id/:token_person2/image
person////
////

Could someone help me?


Solution

  • You don't want to match :: and apparently also not :/

    What you can do is use a single negative lookahead to assert that those 2 strings do not occur.

    ^(?![/\w:]*:[:/])[/\w:]*$
    

    Explanation

    • ^ Start of string
    • (?![/\w:]*:[:/]) Negative lookahead, assert not :: or :/ to the right
    • [/\w:]* Optionally repeat matching one of /, \w (word character) or :
    • $ End of string

    const regex = /^(?![/\w:]*:[:/])[/\w:]*$/;
    [
      "",
      "/",
      ":id",
      "/:id",
      "/:id/",
      "person/:name/:id/:token_person2/image",
      "person////",
      "////",
      ":::id",
      "person/:/name",
    ].forEach(s =>
      console.log((regex.test(s) ? "" : "No ") + `Match --> '${s}'`)
    )

    See a regex demo