0

While I was looking for a way to return url parameter values, I've come across this bit of code.

Reference: https://html-online.com/articles/get-url-parameters-javascript/

function getUrlParts(href) {
 var partsSet = {};
 var parts = href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(a,key,value) {
 partsSet[key] = value;
 });
 return partsSet;
}

I managed to use this code to achieve what I wanted to do however I don't understand it. I tried to punch that regex bit on various regex utility website but no luck. I don't understand " , function(a,key,value) " this part as well. Please explain how could this code return url parameter values.

asked Oct 3, 2019 at 16:14
9
  • Did you looked at this String.replace MDN ? Commented Oct 3, 2019 at 16:16
  • Hi, yes var str = "hi android"; var rep = str.replace("hi", "hello") and hi changes into hello. I was trying to apply this concept into that bit of code above but I don't get it due to "function (a,key,value) Commented Oct 3, 2019 at 16:23
  • 1
    Read the description given in the above link, callback of replaced function accepts different arguments, i.e (complete match, gourp1, gourp2...)` Commented Oct 3, 2019 at 16:24
  • There are better ways... see developer.mozilla.org/en-US/docs/Web/API/URL Commented Oct 3, 2019 at 16:27
  • 1
    Fair enough, the capture groups, indicated by () in the regex, are key to understanding what is going on with this code. replace() is passing the entire match as the first parameter of the replacement function and then each of the capture group matches to the following two parameters of the replacement function. Each key and value are then being set as a key / value pair in the partsSet object. Commented Oct 3, 2019 at 16:50

1 Answer 1

2

⚠️ The answer to your question follows, but please note that in 2019 you should probably not be using this code. See the end of my answer for a better solution. ⚠️

Regexper does a pretty good job of demonstrating what this regular expression will match:

Railroad diagram from Regexper.com

In English, you can read this as:

  1. One or more ? or & characters, followed by
  2. group #1: one or more characters that aren't = or &, followed by
  3. an =, followed by
  4. group #2: zero or more characters that aren't &

Group #1 captures the parameter names and group #2 captures their values.

As for the callback function (function(a,key,value) { ...) passed to replace, let's ask MDN:

You can specify a function as the second parameter. In this case, the function will be invoked after the match has been performed. The function's result (return value) will be used as the replacement string. ... Note that the function will be invoked multiple times for each full match to be replaced if the regular expression in the first parameter is global.

The arguments to the function are as follows:

  • match – The matched substring.
  • p1, p2, ... – The nth string found by a parenthesized capture group, provided the first argument to replace() was a RegExp object.
  • ...

(Source: MDN: String.prototype.replace – Specifying a function as a parameter)

(I've omitted the rest as it doesn't pertain to our question.)

What this tells us is that the function is called for every match, i.e. every parameter name-value pair in the string, and that the second argument (p1, or key in your code) holds the string captured by group #1 and the third argument (p2/value) holds the string captured by group #2.

The code you've found is really using replace for its side-effect: It's a really simple way to iterate all of the matches in a string.


A better way

As noted in the blog post you linked to, if you're targeting current browsers, instead of parsing the query string manually you should use URLSearchParams, which is intended for this exact purpose:

const query = '?foo=1&bar=2';
const searchParams = new URLSearchParams(query);
// Get a specific param
const foo = searchParams.get('foo');
console.log('got foo:', foo);
// Iterate over all params
searchParams.forEach((val, key) => console.log(key, 'is', val));

URLSearchParams works in all modern browsers, including MS Edge ≥ 17 (but not IE). The also exist polyfills for older browsers.

answered Oct 3, 2019 at 16:52

1 Comment

Thank you so much for your kind and descriptive explanation. it helped me finally to understand it. I will make sure to re write the code using the better way you suggested.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.