正则表达式不够贪心

时间:2010-06-15 14:09:31

标签: regex language-agnostic regex-greedy

我得到了以下正则表达式,直到出现新情况

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

基本上,它用于对抗URL,在U =或URL =之后获取一切,并在URL匹配中返回

所以,对于以下

http://localhost?a=b&u=http://otherhost?foo=bar

网址= http://otherhost?foo=bar

不幸的是出现了一个奇怪的案例

http://localhost?a=b&u=http://otherhost?foo=bar&url=http://someotherhost

理想情况下,我希望网址为“http://otherhost?foo=bar&url=http://someotherhost”,而只是“http://someotherhost

编辑:我认为这解决了它......虽然它不是很好

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

1 个答案:

答案 0 :(得分: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 }}

附件

相关问题


修复

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

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

或者你可以完全摆脱前缀匹配部分(see on rubular.com):

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