5

Given this query string:

?cgan=1&product_cats=mens-jeans,shirts&product_tags=fall,classic-style&attr_color=charcoal,brown&attr_size=large,x-small&cnep=0

How can I extract the values from only these param types 'product_cat, product_tag, attr_color, attr_size' returning only 'mens-jeans,shirts,fall,classic-style,charcoal,brown,large,x-small?

I tried using a non-capturing group for the param types and capturing group for just the values, but its returning both.

(?:product_cats=|product_tags=|attr\w+=)(\w|,|-)+
Wiktor Stribiżew
  • 484,719
  • 26
  • 302
  • 397
Benjamin
  • 645
  • 1
  • 7
  • 23

5 Answers5

2

You can collect tha values using

(?:product_cats|product_tags|attr\w+)=([\w,-]+)

Mind that a character class ([\w,-]+) is much more efficient than a list of alternatives ((\w|,|-)*), and we avoid the issue of capturing just the last single character.

Here is a code sample:

var re = /(?:product_cats|product_tags|attr\w+)=([\w,-]+)/g; 
var str = '?cgan=1&product_cats=mens-jeans,shirts&product_tags=fall,classic-style&attr_color=charcoal,brown&attr_size=large,x-small&cnep=0';
var res = [];
while ((m = re.exec(str)) !== null) {
    res.push(m[1]);
}
document.getElementById("res").innerHTML = res.join(",");
<div id="res"/>
Wiktor Stribiżew
  • 484,719
  • 26
  • 302
  • 397
  • This works great. Do you think this is an efficient way to achieve this. Thanks for tips on character classes. – Benjamin Jun 01 '15 at 09:32
  • If you are using plain JS, this is a good way to obtain data from your query string. If you prefer a function that would return values by a provided key name, you can have a look at [this SO post](http://stackoverflow.com/a/2091331/3832970). – Wiktor Stribiżew Jun 01 '15 at 09:40
1

You can use following simple regex :

/&\w+=([\w,-]+)/g

Demo

You need to return the result of capture group and split them with ,.

var mystr="?cgan=1&product_cats=mens-jeans,shirts&product_tags=fall,classic-style&attr_color=charcoal,brown&attr_size=large,x-small&cnep=0
";
var myStringArray = mystr.match(/&\w+=([\w,-]+)/g);
var arrayLength = myStringArray.length-1; //-1 is because of that the last match is 0
var indices = [];
for (var i = 0; i < arrayLength; i++) {
    indices.push(myStringArray[i].split(','));
}
kasravnd
  • 94,640
  • 16
  • 137
  • 166
1

You can always use a jQuery method param.

stile17
  • 182
  • 8
0

Something like

/(?:product_cats|product_tag|attr_color|attr_size)=[^,]+/g
  • (?:product_cats|product_tag|attr_color|attr_size) will match product_cats or product_tag or attr_color or attr_size)

  • = Matches an equals

  • [^,] Negated character class matches anything other than a ,. Basically it matches till the next ,

Regex Demo

Test

string = "?cgan=1&product_cats=mens-jeans,shirts&product_tags=fall,classic-style&attr_color=charcoal,brown&attr_size=large,x-small&cnep=0";

matched = string.match(/(product_cats|product_tag|attr_color|attr_size)=[^,]+/g);  

for (i in matched)
{
console.log(matched[i].split("=")[1]);
}

will produce output as

mens-jeans
charcoal
large
nu11p01n73R
  • 24,873
  • 2
  • 34
  • 48
0

There is no need for regular expressions. just use splits and joins.

var s = '?cgan=1&product_cats=mens-jeans,shirts&product_tags=fall,classic-style&attr_color=charcoal,brown&attr_size=large,x-small&cnep=0';

var query = s.split('?')[1],
    pairs = query.split('&'),
    allowed = ['product_cats', 'product_tags', 'attr_color', 'attr_size'],
    results = [];

$.each(pairs, function(i, pair) {
  var key_value = pair.split('='),
      key = key_value[0],
      value = key_value[1];

  if (allowed.indexOf(key) > -1) {
    results.push(value);
  }
});

console.log(results.join(','));

($.each is from jQuery, but can easily be replaced if jQuery is not around)

yoavmatchulsky
  • 2,912
  • 1
  • 14
  • 22
  • This indeed would work. However I forgot to mention that I will not always know what the value of the attribute params (attr_?) will be unlike 'product_cats' and 'product_tags'. So I think I would need to rely on a regex for this one. – Benjamin Jun 01 '15 at 09:27
  • well, you can always change the allowed list/condition, e.g. `if (allowed.indexOf(key) > -1 || key.indexOf('attr_') === 0)` . but that's up to you. I generally try to avoid regexp when possible. I think that if something can be solved with string manipulations, it will be better read and perform better than regexp – yoavmatchulsky Jun 01 '15 at 10:23