3

在出现新情况之前,我有以下正则表达式运行良好

^.*[?&]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>.*)$
4

1 回答 1

9

问题

问题不在于.*不够贪婪。就是前面出现的另一个 也是贪婪的。.*

为了说明这个问题,让我们考虑一个不同的例子。考虑以下两种模式;它们是相同的,除了\1在第二种模式中不情愿:

              \1 greedy, \2 greedy         \1 reluctant, \2 greedy
              ^([0-5]*)([5-9]*)$           ^([0-5]*?)([5-9]*)$

这里我们有两个捕获组。\1捕捉[0-5]*\2捕捉[5-9]*。以下是这些模式匹配和捕获的内容的并排比较:

              \1 greedy, \2 greedy          \1 reluctant, \2 greedy
              ^([0-5]*)([5-9]*)$            ^([0-5]*?)([5-9]*)$
Input         Group 1    Group 2            Group 1    Group 2
54321098765   543210     98765              543210     98765
007           00         7                  00         7
0123456789    012345     6789               01234      56789
0506          050        6                  050        6
555           555        <empty>            <empty>    555
5550555       5550555    <empty>            5550       555

请注意,虽然贪婪\2,但它只能抢先\1没有抢到的东西!因此,如果你想\2尽可能多地抢5,你必须\1勉强,所以5实际上是由\2.

附件

相关问题


修复

因此,将其应用于您的问题,有两种方法可以解决此问题:您可以让第一个.*不情愿,所以(参见 rubular.com):

^.*?[?&]U(?:RL)?=(?<URL>.*)$

或者,您可以完全摆脱前缀匹配部分(参见 rubular.com):

[?&]U(?:RL)?=(?<URL>.*)$
于 2010-06-15T14:14:56.433 回答