1

I need to parse the url /domain.com?filter[a.b.c]=value1&filter[a.b.d]=value2 and get 2 groups: 'a.b.c' and 'a.b.d'.

I try to parse with regexp [\?&]filter\[(.+\..+)+\]= but the result is 'a.b.c]=value1&filter[a.b.d'. How can I specify to search for the 1st occurrence?

2 Answers 2

1

You may use

/[?&]filter\[([^\].]+\.[^\]]+)]=/g

See the regex demo

Details

  • [?&] - a ? or &
  • filter\[ - a filter[ substring
  • ([^\].]+\.[^\]]+) - Capturing group 1:
    • [^\].]+ - 1 or more chars other than ] and .
    • \. - a dot
    • [^\]]+ - 1 or more chars other than ]
  • ]= - a ]= substring

JS demo:

var s = '/domain.com?filter[a.b.c]=value1&filter[a.b.d]=value2';
var rx = /[?&]filter\[([^\].]+\.[^\]]+)]=/g;
var m, res=[];
while(m=rx.exec(s)) {
  res.push(m[1]);
}
console.log(res);

Note that in case & is never present as part of the query param value, you may add it to the negated character classes, [^\].]+ => [^\]&.]+, to make sure the regex does not overmatch across param values.

Since you need to extract text inside outer square brackets that may contain consecutive [...] substrings with at least 1 dot inside one of them, you may use a simpler regex with a bit more code:

var strs = ['/domain.com?filter[a.b.c]=value1&filter[a.b.d]=value2', 
'/domain.com?filter[a.b.c]=value1&filter[a.b.d]=value2&filter[a][b.e]=value3', 
'/domain.com?filter[a.b.c]=value1&filter[b][a.b.d][d]=value2&filter[a][b.e]=value3'];
var rx = /[?&]filter((?:\[[^\][]*])+)=/g;
for (var s of strs) {
  var m, res=[];
  console.log(s);
  while(m=rx.exec(s)) {
    if (m[1].indexOf('.') > -1) {
      res.push(m[1].substring(1,m[1].length-1));
    }
  }
  console.log(res);
  console.log("--- NEXT STRING ----");
}

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you, it works. Can I make expression more complicate? /domain.com?filter[a.b.c]=value1&filter[a.b.d]=value2&filter[a][b.e]=value3 We should to get 3 groups: 'a.b.c', 'a.b.d' and 'a][b.e' (or 'b.e.')
@Alexander It will be a bit too complex with a single regex. You may do it with a bit simpler regex and a bit of code.
I written so: [?&]filter\[([^=.]+\.[^\]]+)]= Is it have any problems?
@Alexander The problem is that you may overflow across square brackets as [^=.]+ matches any 1+ chars other than = and . (i.e. it matches [ and ], and may match a part of one value and then the whole substring till the matching ending part).
1
(?<=[\?&]filter\[)([^\]]+\.[^\]]+)+(?!>\]=)

This will give you only the groups you mentioned (a.b.c and a.b.d)

This part (?<=[\?&]filter\[) says recognise but don't capture [?&]filter before what you want and this part (?!>\]=) says recognise but don't capture after ] after what you want.

[^\]] this captures everything that isn't a square bracket

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.