I am using JavaScript and I need a regex expression to match everything between "foo".

When I use the following string.

&foo=test1&foo=test2&foo=test3%20test4

It should return

match1: test1
match2: test2
match3: test3%20test4

I tried the following expression

((&foo=)(.*))*

but unfortunately it returned the whole string.

How can I improve my regex expression?

3 Answers

2
EricG On Best Solutions

This expression does not uses .*, instead it might be safe to add a list of chars in between foo= and the next &, maybe similar to:

foo=([A-z0-9%]+)&?

Then, using capturing groups you can capture anything that you might want to.

You can test/modify/change/practice your expressions in this link, if you like.

enter image description here

RegEx Descriptive Graph

This link helps you to visualizes your expressions:

enter image description here

  • You can add additional boundaries to your expressions, if it might be necessary.
  • You can also expand your list of chars.

JavaScript Test

const regex = /foo=([A-z0-9%]+)&?/gm;
const str = `&foo=test1&foo=test2&foo=test3%20test4&foo=test1&foo=test2&foo=test3%20test4&foo=test1&foo=test2&foo=test3%20test4`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

Edit

Based on toto's advice, it's much better to change A-z to A-Za-z or you can use a-z with flag i, based on Limbo's advice, since A-z also passes some other chars such as [ and ].

foo=([A-Z-a-z0-9%]+)&?
2
sln On

This works, save capture group 1 to an array.

&foo=([\S\s]*?)(?=&foo=|$)

https://regex101.com/r/I5JiIc/1

4
Thom Smith On

Instead of using regular expressions at all, I suggest using the built-in URLSearchParams class:

const params = new URLSearchParams('&foo=test1&foo=test2&foo=test3%20test4');

params.getAll('foo');
// ["test1", "test2", "test3 test4"]

Works in all major browsers. (Needs a polyfill for IE 11, if that matters to you.)