3

我正在尝试编写一个仅对包含 FOO 的 BAR 字符串为真的正则表达式。

例如,正则表达式不会匹配这个:

FOO IS BAR

但会匹配这个:

BAZ IS BAR
4

3 回答 3

4
(?<!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...

于 2013-03-05T18:48:11.870 回答
3

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..
于 2013-03-05T18:48:01.930 回答
1

您可能会发现将其放入两个正则表达式更容易。例如,如果我们在谈论 Perl,你可以这样做

if ( /BAR/ && !/FOO.*BAR/ )

对我来说,这比试图做负面的回顾要清楚得多。

由于您似乎在 PHP 中,我认为 preg_match on/BAR/和另一个 on not matching没有任何问题/FOO.*BAR/

于 2013-03-05T19:02:04.560 回答