Reputation: 45
This is my first question asked of the stack because, well, I just really can't wrap my brain around regex. I am trying to rig a university library's advanced catalog search so that after a patron searches, say, "football" in several different categories of material types, hitting a "modify your search" button returns them to the form with all their previous search parameters remembered. It's an old, proprietary system, so what it does by default is return the patron to the search form but force them to start from scratch.
The location string still has all the parameters, though, so what I want to do is regex that and populate the form with JS. This is what the string looks like:
/search~S13/X?NOSRCH=(football)&m=i&m=g&m=r&m=r&m=1&m=5&m=g&m=o&m=7&m=j&m=i&m=2&m=3&m=q&m=m&SORT=D&SUBKEY=(football)
I want to grab the value of m, which can occur a lot more times than the above example. So far, I'm doing this:
var str = location.search.match(/m.*?&/g);
which returns
"m=i&", "m=g&", "m=r&", "m=r&", "m=1&", "m=5&", "m=g&", "m=o&", "m=7&", "m=j&", "m=i&", "m=2&", "m=3&", "m=q&", "m=m&"
How would you go about grabbing just the value i
in m=i&
?
Upvotes: 3
Views: 247
Reputation: 3184
I may have misunderstood your question but I don't think RegEx is necessary, if you're using JavaScript.
In any case, first, get the search part of the string and slice the question mark off the beginning, e.g.,
var str = window.location.search.slice(1);
Then you can either go the RegEx route or the simple JavaScript route.
REGEX:
Create you pattern with a non-capturing and a capturing group (in parentheses):
var regexPttrn = /(?:m\=)([^&=]+)/ig;
The first group uses ?:
to look for the characters m=
. Once it's found them it captures any group of consecutive characters that aren't ampersands or equals signs.
Unfortunately, you have to use the exec
method to do this, and within a loop too, because exec
only does one match at a time and you need to check that the returned array has the property you need before using it, etc.
JAVASCRIPT:
Better still, instead of using RegEx, split str
as defined above into an array of different properties by using the ampersand as a delimiter:
var arr = str.split('&');
So this will create an array of strings, like "m=i"
, "m=g"
, etc.
Then split each of these into key-value pairs, by running a loop and splitting each element of arr
using the equals sign as a delimiter:
var pairs = [];
for (var i = 0; i < arr.length; i += 1) {
pairs[i] = arr[i].split("=");
}
This way you will get an array containing several little arrays, that structurally look like this:
[
[ "NOSRCH", "FOOTBALL" ],
[ "m", "i" ],
[ "m", "g" ],
/* and so on, until... */
[ "EY", "(football)" ]
]
To grab just the value of m
you could modify the above loop to create an array of just those values like so:
var pairs = [],
m_results = [];
for (var i = 0; i < arr.length; i += 1) {
pairs.push(arr[i].split("="));
if (pairs[i][0] === "m") {
m_results.push(pairs[i][1]);
}
}
The array m_results
will then contain all the values associated with m
in your search string.
Just 10 lines of code in all and much easier to comment, debug, and reuse than trying some tortured RegEx pattern I think, though I can see that RegEx would be more concise, if you can get it to capture efficiently.
Upvotes: 1
Reputation: 156444
var s = '/search~S13/X?NOSRCH=(football)&m=i&m=g&m=r&m=r&m=1&m=5&m=g&m=o&m=7&m=j&m=i&m=2&m=3&m=q&m=m&SORT=D&SUBKEY=(football)';
s.split(/&/).map(function(x) {
return x.split(/=/);
}).filter(function(x) {
return x[1] == 'i';
}); // => [['m', 'i'], ['m', 'i']]
Upvotes: 0
Reputation: 56809
Since this is from the location.search
you can do this:
location.search.substring(1).split('&').filter(function (e) {
return /^m=/.test(e);
}).map(function (e) {
return e.substring(2);
});
The first substring
is to remove ?
from the query string in location.search
.
Upvotes: 1
Reputation: 336218
I can show you how you can iterate over the string; you probably know JavaScript better than I do, so you know how to make an array out of these results:
var myregexp = /\bm=([^&]*)/g;
var match = myregexp.exec(subject);
while (match != null) {
// matched text: match[1], add that to your result array
}
match = myregexp.exec(subject);
}
Explanation of the regex:
\b # Start at the beginning of an alphanumeric "word"
m= # (in this case, it's just one letter) "m", followed by "="
( # Match and capture in group number 1:
[^&]* # any number of characters except ampersands
) # End of capturing group.
As far as I know, there's no direct way to populate an array containing only matches from a capturing group, not matches of the entire regex.
Upvotes: 1