programmer33
programmer33

Reputation: 652

Parsing URL Query Parameters using regex

I would like to parse url query params intelligently using regex.

Things I've had to consider: 1) params can be out of order 2) only certain params must match

Given a query string: "?param1=test1&param2=test2&parm3=test3" I would like to run javascript regex to parse param1's value and param3's value.

The regex I've come up with so far is:

/(?:[?&](?:param1=([^&]*)|param3=([^&]*)|[^&]*))+$/g

This regex seems to work fine for me in sites like https://regex101.com/.

However, when I run the JS method below, I always get undefined for $2, which is what param1's value should be parsing to. Any help or suggestion?

"?param1=test1&param2=test2&param3=test3".replace(
/(?:[?&](?:param1=([^&]*)|param3=([^&]*)|[^&]*))+$/g,
 function ($0, $1, $2, $3) { return $0 + ' ' + $1 + ' ' + $2 + ' ' + $3; });

This returns $2 as undefined and $3 as test3. However, if I exclude both param2 and param3 from the url query string, I am successfully able to parse param1 as $2. A bit confused about that.

thanks!

Upvotes: 1

Views: 9214

Answers (2)

David Rechtman
David Rechtman

Reputation: 313

.*parameterName=([^&|\n|\t\s]+)

Using this pattern will give you in a group the parameter value. For example for this URL: https://www.youtube.com/watch?v=aiYpDDHKy18&list=RDaiYpDDHKy18&start_radio=1

.*list=([^&|\n|\t\s]+)

will get you: the list id: "RDaiYpDDHKy18"

.*start_radio=([^&|\n|\t\s]+)

will get you the number 1.

Upvotes: 3

Sebastian Lenartowicz
Sebastian Lenartowicz

Reputation: 4864

If they're in an arbitrary order, you can use lookaheads to find them and capture the param values. The pattern you want (for your test string) is this:

^(?=.*param1=([^&]+)|)(?=.*param2=([^&]+)|)(?=.*param3=([^&]+)|).+$

Demo on Regex101

It'll also accept query strings that are missing parameters, because each lookahead alternates on either the parameter/value pair or the empty string, using the |s at the end.

You'll need an additional lookahead for each parameter you hope to grab, and there's no way around this. Because every regex under the sun is a state machine under the hood, the only thing you're gonna be hanging on to using your original pattern is the most recent match for a given capture group.

Upvotes: 0

Related Questions