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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.