Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-greedy capturing parenthesis

I have the string mysql://user:pw@host/db?reconnect=true and the following (incorrect) regex: /^mysql:\/\/(.+):(.+)@(.+)\/(.+)\??.*$/

These are the matches I get:

["user", "pw", "host", "db?reconnect=true"]

The only problematic match is "db?reconnect=true", which I intend to be "db"

I have tried non-greedy qualifiers for both the "?" after "db" and after the last capturing parenthesis with no success. It seems like the last capturing parenthesis is greedy no matter what. Is there even a solution for this?

Cheers!

like image 831
Maxime Dupré Avatar asked Feb 07 '26 04:02

Maxime Dupré


2 Answers

All of your quantifiers are greedy; you need to add ? to make them non-greedy. In this specific case, you need to be careful, because if you don't ensure it must match the GET query separately, non-greediness will omit the b in db too. There are two decent options here:

  1. Explicitly non-greedy: /^mysql:\/\/(.+):(.+)@(.+)\/(.+?)(?:\?.*)?$/ (You need to group the ? with the rest of GET query; if it's optional by itself, the non-greedy code will stop early, ignore the optional ?, and just shove everything into the match on the greedy .*)
  2. Greedy, but excluding ? from the things it's willing to match: /^mysql:\/\/(.+):(.+)@(.+)\/([^?]+)(?:\?.*)?$/ Since a ? can't occur in a legal URL except when splitting the GET query, we swap from .+ to [^?]+ to keep everything until the ?
like image 131
ShadowRanger Avatar answered Feb 09 '26 01:02

ShadowRanger


You can use a negated character class [^?] to match anything except a question mark ?.

Try this:

^mysql:\/\/(.+?):(.+?)@(.+?)\/([^?]+)

Regex101

Group 1.    `user`
Group 2.    `pw`
Group 3.    `host`
Group 4.    `db`
like image 40
K.Dᴀᴠɪs Avatar answered Feb 09 '26 01:02

K.Dᴀᴠɪs



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!