2011-11-22 29 views
5

正規表現で論理演算子 "AND"を使用したいと思います。 は、私はこれを試してみました:論理演算子ANDとPHP正規表現

(?=exp1)(?=exp2) 

しかし、PHP ?=では動作し、PHP言語での私のプログラムを記述する必要はありません。別の方法がありますか?すべての条件が存在し、任意の順序で存在する場合、式は一致しなければなりません。

(exp1)(exp2)(exp3)|(exp1)(exp3)(exp2)|.... 
+0

正規表現を分割する必要があると思います – DiogoDoreto

+4

うーむ。 phpは '(?= ...)'をサポートしています:http://php.net/manual/en/regexp.reference.assertions.php –

答えて

9

PHPは先読み式をサポートしています: 私のようなすべての順列を書きたくありません。あなたはおそらくそれらを正しく使用していないでしょう。

あなたがfoobarbazの3つすべてを含む文字列を一致させたいと仮定すると、あなたは正規表現を必要とする

^(?=.*foo)(?=.*bar)(?=.*baz) 

これは、しかし、その試合を文字列foobarbazまたはbarbazfooなどの一致を返します。先読みは文字を消費しないため、空の文字列になります。あなたは正規表現が文字列自体を返すようにしたい場合は、それはすべての3つの基準を満たすならば、文字列全体にマッチします

^(?=.*foo)(?=.*bar)(?=.*baz).* 

を使用しています。

私は単に

if (preg_match('/^(?=.*foo)(?=.*bar)(?=.*baz)/s', $subject)) { 
    # Successful match 
} else { 
    # Match attempt failed 
} 

が、これがまたfoonly bartender bazookaのような文字列にマッチしますのでご注意ください使用します。あなたは(だけの3つの式のそれぞれの純粋な順列を許可する)ことをしたくない場合は、ちょっとしたトリックでそれを行うことができます。

^(?:foo()|bar()|baz()){3}\1\2\3$ 

試合foobarbazfoobazbarbarfoobazbarbazfoobazfoobarbazbarfoo(何もありません)。 "トリック"は、Jan GoyvaertsとSteven Levithanの優れた本"Regular Expressions Cookbook"(p。304)に触発されています。次のように動作する:

  • 必要な各部分(foo等)が必要な部分が一致した場合に常に一致する空のキャプチャグループ()が続きます。
  • 3つの必須部分がすべて一致した場合、3つの空のキャプチャグループがすべて一致しています。
  • 以下の後方参照は、各キャプチャグループがマッチに参加した場合にのみ成功します。
  • 文字列がfoobarbarの場合、(?:foo()|bar()|baz()){3}の部分は一致しますが、\3は失敗し、正規表現全体が失敗します。
  • しかし、キャプチャグループのそれぞれに空の文字列だけが含まれているため、3つすべてが一致に含まれた場合、\1\2\3は文字列の最後で一致します。 @ティムの答えに加えて
+0

良い、完全な答え。 +1 – FailedDev

+0

@timこれにリソースや補足情報を提供できますか?私はfoo()| bar()| baz()のようなものは見たことがありません。 – bozdoz

+0

私は何を求めているのでしょうか?空の括弧の意味は何ですか? – bozdoz

1

(?=exp1)(?=exp2) 

これが本当であることはできません。あなたは普通の英語で言う:ここに続くテキストがexp1であることを確認し、ここに続くテキストがexp2であることを確認する。これは真実ではありません。それは決して一致しません。