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>.*)$