正则表达式匹配字符串BAR,只要字符串FOO不出现在它之前


Regex matching string BAR as long as string FOO does not occur before it

我试图写一个正则表达式,这是唯一的字符串包含BAR,不前面有FOO。

例如,正则表达式将不匹配:

FOO IS BAR

But WOULD匹配this:

BAZ IS BAR
(?<!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函数,以便能够使用look - around断言。

但我认为有一种方法可以与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中,我看到/BAR/上的preg_match和另一个不匹配/FOO.*BAR/没有什么问题。