Regex не достаточно жадный - PullRequest
3 голосов
/ 15 июня 2010

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

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

1 Ответ

9 голосов
/ 15 июня 2010

выпуск

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

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