I am trying to parse url-encoded strings that are made up of key=value pairs separated by either &
or &
.
The following will only match the first occurrence, breaking apart the keys and values into separate result elements:
var result = mystring.match(/(?:&|&)?([^=]+)=([^&]+)/)
The results for the string '1111342=Adam%20Franco&348572=Bob%20Jones' would be:
['1111342', 'Adam%20Franco']
Using the global flag, 'g', will match all occurrences, but only return the fully matched sub-strings, not the separated keys and values:
var result = mystring.match(/(?:&|&)?([^=]+)=([^&]+)/g)
The results for the string '1111342=Adam%20Franco&348572=Bob%20Jones' would be:
['1111342=Adam%20Franco', '&348572=Bob%20Jones']
While I could split the string on &
and break apart each key/value pair individually, is there any way using JavaScript's regular expression support to match multiple occurrences of the pattern /(?:&|&)?([^=]+)=([^&]+)/
similar to PHP's preg_match_all()
function?
I'm aiming for some way to get results with the sub-matches separated like:
[['1111342', '348572'], ['Adam%20Franco', 'Bob%20Jones']]
or
[['1111342', 'Adam%20Franco'], ['348572', 'Bob%20Jones']]
For capturing groups, I'm used to using
preg_match_all
in PHP and I've tried to replicate it's functionality here:You need to use the 'g' switch for a global search
To capture several parameters using the same name, I modified the while loop in Tomalak's method like this:
input:
?firstname=george&lastname=bush&firstname=bill&lastname=clinton
returns:
{firstname : ["george", "bill"], lastname : ["bush", "clinton"]}
To avoid regex hell you could find your first match, chop off a chunk then attempt to find the next one on the substring. In C# this looks something like this, sorry I've not ported it over to JavaScript for you.
Set the
g
modifier for a global match:If you don't want to rely on the "blind matching" that comes with running
exec
style matching, JavaScript does come with match-all functionality built in, but it's part of thereplace
function call, when using a "what to do with the capture groups" handling function:done.
Instead of using the capture group handling function to actually return replacement strings (for replace handling, the first arg, called
a
here, is the full pattern match, and subsequent args are individual capture groups, in this caseb
being group 1,c
group 2, etc) we simply take the groups 2 and 3 captures, and cache that pair.So, rather than writing complicated parsing functions, remember that the "matchAll" function in JavaScript is simply "replace" with a replacement handler function, and much pattern matching efficiency can be had.