非贪婪捕获括号

Non-greedy capturing parenthesis

我有字符串 mysql://user:pw@host/db?reconnect=true 和以下(不正确的)正则表达式:/^mysql:\/\/(.+):(.+)@(.+)\/(.+)\??.*$/

这些是我得到的匹配项:

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

唯一有问题的匹配项是 "db?reconnect=true",我打算将其设为 "db"

我已经为“?”尝试了非贪婪限定符。在 "db" 之后和最后一个捕获括号之后没有成功。无论如何,最后一个捕获括号似乎都是贪婪的。甚至有解决方案吗?

干杯!

您可以使用否定字符 class [^?] 来匹配任何内容 除了 问号 ?.

试试这个:

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

Regex101

Group 1.    `user`
Group 2.    `pw`
Group 3.    `host`
Group 4.    `db`

你所有的量词都是贪心的;您需要添加 ? 以使它们不贪婪。在这种特定情况下,您需要小心,因为如果您不确保它必须单独匹配 GET 查询,非贪婪也会省略 b in db。这里有两个不错的选择:

  1. 显式非贪婪:/^mysql:\/\/(.+):(.+)@(.+)\/(.+?)(?:\?.*)?$/(您需要将 ? 与 GET 查询的其余部分组合在一起;如果它本身是可选的,非贪婪代码将提前停止,忽略可选 ?,然后将所有内容都推入贪婪 .*)
  2. 的匹配中
  3. 贪心,但从它愿意匹配的事物中排除 ?/^mysql:\/\/(.+):(.+)@(.+)\/([^?]+)(?:\?.*)?$/ 因为 ? 不能出现在合法的 URL 中,除非拆分GET 查询,我们从 .+ 交换到 [^?]+ 以保留所有内容,直到 ?