正则表达式不够贪婪
我有以下正则表达式,在出现新情况之前一直运行良好
^.*[?&]U(?:RL)?=(?<URL>.*)$
基本上,它用于针对 URL,以获取 U= 或 URL= 之后的所有内容并在 URL 匹配中返回它
因此,对于以下
http://localhost?a=b&u=http://otherhost?foo= bar
URL = http://otherhost?foo=bar
不幸的是出现了一个奇怪的情况
http://localhost?a=b& u=http://otherhost?foo=bar&url=http://someotherhost
理想情况下,我希望 URL 为“http://otherhost?foo=bar&url=http://someotherhost",相反,它只是“http://someotherhost”
编辑:我认为这解决了它......虽然它不太漂亮
^.*[?&](?<![?&]U(?:RL)?=.*)U(?:RL)?=(?<URL>.*)$
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题问题
不在于
.*
不够贪婪;而是在于。而是之前出现的其他.*
也是贪婪。为了说明这个问题,让我们考虑一个不同的例子。考虑以下两种模式;它们是相同的,除了第二种模式中不愿意使用
\1
:这里我们有两个捕获组。
\1
捕获[0-5]*
,\2
捕获[5-9]*
。以下是这些模式匹配和捕获的内容的并排比较:请注意,尽管
\2
很贪婪,但它只能捕获\1
尚未捕获的内容先抢!因此,如果你想让\2
抓取尽可能多的5
,你就必须让\1
不情愿,所以5
实际上已经被\2
抢占了。附件
相关问题
解决方案
因此,将其应用于您的问题,有两种方法可以解决此问题:您可以使第一个
.*
不情愿,因此 (< a href="http://www.rubular.com/r/Ks5wB7LNBx" rel="nofollow noreferrer">参见 rubular.com):或者,您可以完全删除前缀匹配部分(< a href="http://www.rubular.com/r/YTm9YuLQVi" rel="nofollow noreferrer">参见 rubular.com):
The issue
The problem is not that
.*
is not being greedy enough; it's that the other.*
that appears earlier is also greedy.To illustrate the issue, let's consider a different example. Consider the following two patterns; they're identical, except in reluctance of
\1
in second pattern:Here we have two capturing groups.
\1
captures[0-5]*
, and\2
captures[5-9]*
. Here's a side-by-side comparison of what these patterns match and capture:Note that as greedy as
\2
is, it can only grab what\1
didn't already grab first! Thus, if you want to make\2
grab as many5
as possible, you have to make\1
reluctant, so the5
is actually up for grab by\2
.Attachments
Related questions
The fix
So applying this to your problem, there are two ways that you can fix this: you can make the first
.*
reluctant, so (see on rubular.com):Alternatively you can just get rid of the prefix matching part altogether (see on rubular.com):