Это пример антипаттерна, который я называю Преждевременное обращение к внешнему виду . Вы знаете, что искомой строке предшествует foo
, за которой следует bar
, и вы знаете, что в регулярных выражениях есть вещи, называемые lookbehinds и lookaheads, поэтому очевидно, что вам следует использовать:
(?<=foo).*(?=bar)
Остерегайся очевидного; очень мало о регулярных выражениях интуитивно понятно. Помните, что предпросмотр был довольно поздним дополнением к регулярным выражениям, а взгляды запаздывали даже позже, но люди решали эту проблему задолго до того, как пришли. Они сделали это, используя группы захвата, и это по-прежнему лучший вариант в большинстве случаев:
foo(.*)bar
В вашем регулярном выражении также есть прямая ошибка: квантификатор ?
на вид сзади:
(?<=mydomain.net)?
Поле поиска EditPadPro помечает это как ошибку, как и PHP; Java и .NET нет, но я считаю, что они должны. Это не имеет больше смысла, чем \b*
или ^+
или ${3,7}
. Все это утверждения нулевой ширины, что означает, что они ничего не соответствуют, поэтому, добавляя квантификатор, вы пытаетесь сопоставить одно и то же ничто несколько раз (помните, что $
не соответствует символу новой строки, просто позиция между перевод строки и предыдущий символ).
Нет опасности застрять в бесконечном цикле, но это хороший признак того, что автор регулярного выражения сделал опечатку или неправильно что-то понял. Это особенно верно, когда квантификатор равен единице, которая может совпадать с нулем раз, например ?
или *
Это делает утверждение необязательным, а необязательное утверждение является несоответствующим утверждением. В вашем регулярном выражении (?<=mydomain.net)?
означает «либо текущей позиции предшествует mydomain.net
, либо нет; мне все равно».
Во всяком случае, Чад уже придумал регулярное выражение, которое работает; Я просто хотел дать некоторое представление о том, почему ваши нет. И полевые испытания моего анти-паттерна, конечно. ;)