正则表达式不够贪心

Caf*_*eek 3 regex language-agnostic regex-greedy

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

^.*[?&]U(?:RL)?=(?<URL>.*)$
Run Code Online (Sandbox Code Playgroud)

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

所以,对于以下内容

HTTP://本地主机A = B&U = HTTP:// OTHERHOST富=酒吧

URL = http:// otherhost?foo = bar

不幸的是,出现了奇怪的情况

HTTP://本地主机A = B&U = HTTP:// OTHERHOST富=栏&URL = HTTP:// someotherhost

理想情况下,我希望URL为" http:// otherhost?foo = bar&url = http:// someotherhost ",相反,它只是" http:// someotherhost "

编辑:我认为这解决了它...虽然它不漂亮

^.*[?&](?<![?&]U(?:RL)?=.*)U(?:RL)?=(?<URL>.*)$
Run Code Online (Sandbox Code Playgroud)

pol*_*nts 9

问题

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

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

              \1 greedy, \2 greedy         \1 reluctant, \2 greedy
              ^([0-5]*)([5-9]*)$           ^([0-5]*?)([5-9]*)$
Run Code Online (Sandbox Code Playgroud)

这里我们有两个捕获组.\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
Run Code Online (Sandbox Code Playgroud)

请注意,因为\2它是贪婪的,它只能抓住\1尚未抢先的东西!因此,如果你想\2尽可能多5地抓住,你必须\1不情愿,所以5实际上是抓住了\2.

附件

相关问题


修复

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

^.*?[?&]U(?:RL)?=(?<URL>.*)$
Run Code Online (Sandbox Code Playgroud)

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

[?&]U(?:RL)?=(?<URL>.*)$
Run Code Online (Sandbox Code Playgroud)

  • 或者只删除`^.*`. (3认同)
  • 不愿意?我通常称之为非贪心.事实上,第一个`.*`太贪心了. (2认同)