FOO が前にない BAR を含む文字列にのみ当てはまる正規表現を作成しようとしています。
たとえば、正規表現はこれと一致しません:
FOO IS BAR
しかし、これと一致します:
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
ルックアラウンド アサーションを使用できるようにするには、関数が必要です。
しかし、私はで動作する方法があると思います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..
2 つの正規表現に入れる方が簡単な場合があります。たとえば、Perl について話している場合は、次のようにすることができます。
if ( /BAR/ && !/FOO.*BAR/ )
これは、否定的な後読みを行うよりもはるかに明確です。
あなたはPHPにいるように見えるので、 preg_match on/BAR/
と別の on not matching に問題はありません/FOO.*BAR/
。