Thomas Thomas - 4 days ago 4
PHP Question

Why does my regex group quantifier not work?

I try to write some regex for Dutch license plates (kentekens), the documentation is very clear and I only want to check them on format, not if the actual alpha character is possible for now.

My regex (regex101) looks as follows:


(([0-9]{1,2}|[a-z]{1,3})-([0-9]{2,3}|[a-z]{2,3})-([0-9]{1,2}|[a-z]{1,2})){8}/gi



However this returns no matched, while


([0-9]{1,2}|[a-z]{1,3})-([0-9]{2,3}|[a-z]{2,3})-([0-9]{1,2}|[a-z]{1,2}/gi



does

However I do like to check the total length as well.

JS Demo snippet



const regex = /([0-9]{1,2}|[a-z]{1,3})-([0-9]{2,3}|[a-z]{2,3})-([0-9]{1,2}|[a-z]{1,2})/gi;
const str = `XX-99-99
2​ 1965​ 99-99-XX ​
3​ 1973​ 99-XX-99​
4​ 1978​ XX-99-XX ​
5​ 1991​ XX-XX-99 ​
6​ 1999​ 99-XX-XX ​
7​ 2005​ 99-XXX-9​
8​ 2009​ 9-XXX-99​
9​ 2006​ XX-999-X ​
10​ 2008​ X-999-XX ​
​11 ​2015 ​XXX-99-X`;
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}`);
});
}




Answer

This is because {8} quantifier added at the end will act on previous expression, in this case the whole regex, because it is enclosed with parenthesis. See here what matches this regex.

To test for length, use this regex (?=^.{1,8}$)(([0-9]{1,2}|[a-z]{1,3})-([0-9]{2,3}|[a-z]{2,3})-([0-9]{1,2}|[a-z]{1,2})) It uses a lookahead to make sure that the following characters match ^.{1,8}$, which means the whole string should contain between 1 and 8 character, you can adjust it to your needs.

Comments