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.
1 Answer 1
⚠️ 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:
- One or more
?
or&
characters, followed by - group #1: one or more characters that aren't
=
or&
, followed by - an
=
, followed by - 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 toreplace()
was aRegExp
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.
String.replace MDN
?replaced
function accepts different arguments, i.e (complete match, gourp1, gourp2...)`()
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 thepartsSet
object.