我正在尝试编写一个仅对包含 FOO 的 BAR 字符串为真的正则表达式。
例如,正则表达式不会匹配这个:
FOO IS BAR
但会匹配这个:
BAZ IS BAR
(?<!FOO.*)BAR
is the correct regex for this (but it only works with the .NET regex engine).
(?<!FOO.*)
is a negative lookbehind assertion that asserts that it's not possible to match any string containing FOO
before the current position.
In PHP, you don't have infinite lookbehind. An alternative would be
^(?:(?!FOO|BAR).)*BAR
Explanation:
^ # 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
However, even this doesn't work with the deprecated ereg
functions. You need preg
functions in order to be able to use lookaround assertions.
But I think there is a way that works with ereg
:
^(FO?|[^FO]|[^O]O)*BAR
Explanation:
^ # 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
However, this will get very complicated very quickly if your exclusion string is more complicated than FOO
...
You can use this regex
^(?=.*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 on/BAR/
和另一个 on not matching没有任何问题/FOO.*BAR/
。