Edited at

正規表現で論理積(AND)を実現する

More than 3 years have passed since last update.


論理和(OR)の場合

ORは簡単にできます。例えば'apple'または'orange'が含まれているかどうか調べる場合は以下のようになります(コードはJavaScript)。

/apple|orange/


論理積(AND)の場合

ANDは、例えば'apple''orange'の両方が含まれているかどうか調べる場合は以下のようにすればいいらしいです。

/^(?=.*apple)(?=.*orange)/


なんで!?

(?=)は位置指定子というものの一つで、x(?=y)としたときは、'x''y'が続く場合のみ'x'にマッチします(肯定先読み)。

つまり、あくまでも位置を指定しているというわけです。

上の例の場合、まず先頭をスタート位置とし、^(先頭)→.*(何かしらの文字が0回以上)→appleと続いているかチェックします。さらにまた先頭から、^(先頭)→.*(何かしらの文字が0回以上)→orangeと続いているかチェックします。

順を追って見ていくと、

"lemon, apple, grape, orange"

という文字列があったときに、^の時点でlの前にマッチします。

"【ここ】lemon, apple, grape, orange"

次に(?=.*apple)の時点で、lemon, appleがそれに該当します。

"【ここから】lemon, apple【ここまで】, grape, orange"

さらにその位置に対して、(?=.*orange)が成立するか見ます。

"【ここから】lemon, apple, grape, orange【ここまで】"

.*の部分はlemon, apple, grape,にあたり、その後orangeが出てきて、この文字列(の先頭)は/^(?=.*apple)(?=.*orange)/にマッチするということになります。

これを利用して、3つ以上のANDを表現するのにも使えます。

/^(?=.*apple)(?=.*orange)(?=.*peach)/.test("lemon, apple, grape, orange"); //false