Why is this javascript non-greedy regex matching nothing?

284 Views Asked by At

Having the url and js regex below, I'd expect to catch the f2fJsDFJ23, but the non-greedy parts .*? and \?? don't work as expected

What's the reasoning?

let t = 'https://www.youtube.com/embed/f2fJsDFJ23?autoplay=1'
let reg = /(?:embed\/)(.*?)(?:\??)/.exec(t)
document.write(`6>>> ${reg && reg.join(' | ')} <br/>`)

reg = /(?:embed\/)(.*)(?:\??)/.exec(t)
document.write(`6>>> ${reg && reg.join(' | ')} <br/>`)

reg = /(?:embed\/)(.*)(?:\?)/.exec(t)
document.write(`6>>> ${reg && reg.join(' | ')} <br/>`)

t = 'https://www.youtube.com/embed/f2fJsDFJ23'
reg = /(?:embed\/)(.*?)(?:\??)/.exec(t)
document.write(`6>>> ${reg && reg.join(' | ')} <br/>`)

reg = /(?:embed\/)(.*)(?:\??)/.exec(t)
document.write(`6>>> ${reg && reg.join(' | ')} <br/>`)

reg = /(?:embed\/)(.*)(?:\?)/.exec(t)
document.write(`6>>> ${reg && reg.join(' | ')} <br/>`)

1

There are 1 best solutions below

0
The fourth bird On BEST ANSWER

In your pattern the (.*?) part is non greedy giving up as least as possible. After that it will match an optional question mark. As the question mark is optional the the dot non greedy, the pattern will suffice matching embed/ only.

One option is to match either ? or assert the end of the string $ using an alternation.

Note that you can omit the non capturing group around embed and the question mark.

embed\/(.*?)(?:\?|$)

Regex demo


Another option is to use a negated character class matching any char except a ? or a whitespace char:

embed\/([^?\s]*)

Regex demo