非贪婪捕获括号

时间:2018-12-11 02:15:00

标签: javascript regex regex-greedy capturing-group

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

这些是我得到的比赛:

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

唯一有问题的匹配是"db?reconnect=true",我打算是"db"

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

干杯!

2 个答案:

答案 0 :(得分:2)

您可以使用否定的字符类[^?]来匹配任何 问号?之外的字符。

尝试一下:

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

Regex101

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

答案 1 :(得分:2)

您所有的量词都是贪婪的;您需要添加?使其不贪心。在这种情况下,您需要格外小心,因为如果不确保它必须单独与GET查询匹配,则出于非贪婪的考虑,b中的db也将被忽略。这里有两个不错的选择:

  1. 显式非贪婪:/^mysql:\/\/(.+):(.+)@(.+)\/(.+?)(?:\?.*)?$/(您需要将?与其余的GET查询分组;如果它本身是可选的,则非贪婪代码将尽早停止,请忽略可选的{ {1}},然后将所有内容都塞进贪婪的?
  2. 贪婪,但将.*从其愿意匹配的内容中排除:?由于/^mysql:\/\/(.+):(.+)@(.+)\/([^?]+)(?:\?.*)?$/不能在合法URL中出现,除非拆分GET查询时,我们从从?.+保留所有内容,直到[^?]+