Regex не достаточно жадный

У меня есть следующее регулярное выражение, которое работало отлично, пока не возникла новая ситуация

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

По сути, он используется против URL, чтобы захватить ВСЕ после U = или URL= и вернуть его в соответствии URL

Итак, для следующего

HTTP: // локальный а = Ь & и = HTTP: //? otherhost Foo = бар

URL= http://otherhost/?foo=bar

К сожалению, возник странный случай

HTTP: // локальный а = Ь & и = HTTP: // otherhost Foo = бар и URL= HTTP: // someotherhost

В идеале я хочу, чтобы URL был " http://otherhost/?foo=bar&url=http://someotherhost", вместо этого это просто " http://someotherhost/"

РЕДАКТИРОВАТЬ: Я думаю, что это исправило... хотя это не красиво

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

1 ответ

Решение

Проблема

Проблема не в том .* недостаточно жаден; это то, что другой .* то, что появляется раньше, тоже жадное.

Чтобы проиллюстрировать проблему, давайте рассмотрим другой пример. Рассмотрим следующие две модели; они идентичны, за исключением нежелания \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>.*)$
Другие вопросы по тегам