Регулярное сопоставление строки BAR до тех пор, пока строка FOO не появится перед ней
Я пытаюсь написать регулярное выражение, которое верно только для строки, содержащей BAR, которому не предшествует FOO.
Например, регулярное выражение не будет соответствовать этому:
FOO IS BAR
Но соответствовало бы этому:
BAZ IS BAR
3 ответа
(?<!FOO.*)BAR
является правильным регулярным выражением для этого (но это работает только с механизмом регулярных выражений.NET).
(?<!FOO.*)
является отрицательным утверждением, которое утверждает, что невозможно сопоставить любую строку, содержащую FOO
до текущей позиции.
В PHP у вас нет бесконечного взгляда назад. Альтернативой будет
^(?:(?!FOO|BAR).)*BAR
Объяснение:
^ # Start of string
(?: # Match...
(?! # (unless the following can be matched here:
FOO # either FOO
| # or
BAR # BAR)
) # (end of lookahead)
. # ... any character.
)* # Repeat as needed
BAR # Match BAR
Тем не менее, даже это не работает с устаревшими ereg
функции. Тебе нужно preg
функции для того, чтобы иметь возможность использовать косвенные утверждения.
Но я думаю, что есть способ, который работает с ereg
:
^(FO?|[^FO]|[^O]O)*BAR
Объяснение:
^ # Start of string
( # Either match:
FO? # F or FO
| # or
[^FO] # any character except F or O
| # or
[^O]O # any non-O character followed by O
)* # any number of times
BAR # Then match BAR
Однако это будет очень сложно очень быстро, если ваша строка исключения будет более сложной, чем FOO
...
Вы можете использовать это регулярное выражение
^(?=.*BAR)(?!.*?FOO.*?BAR).*$
--------- --------------
| |
| |proceed only if there's no FOO before BAR...
|->proceed only if there's a BAR...CHEERS..
Возможно, вам будет проще поместить его в два регулярных выражения. Если мы говорим на Perl, например, вы могли бы сделать
if ( /BAR/ && !/FOO.*BAR/ )
что для меня гораздо яснее, чем пытаться сделать негативный взгляд назад.
Поскольку вы, кажется, находитесь в PHP, я не вижу ничего плохого в preg_match на /BAR/
и еще один не соответствует /FOO.*BAR/
,