Регулярное сопоставление строки 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/,

Другие вопросы по тегам