2

I figured out how to check an OR case, preg_match( "/(word1|word2|word3)/i", $string );. What I can't figure out is how to match an AND case. I want to check that the string contains ALL the terms (case-insensitive).

Darrell Brogdon
  • 6,843
  • 9
  • 47
  • 62
Shamoon
  • 41,293
  • 91
  • 306
  • 570
  • 2
    Related: http://stackoverflow.com/questions/469913/regular-expressions-is-there-an-and-operator – miku Jan 02 '10 at 19:04

4 Answers4

5

It's possible to do an AND match in a single regex using lookahead, eg.:

preg_match('/^(?=.*word1)(?=.*word2)(?=.*word3)/i', $string)

however, it's probably clearer and maybe faster to just do it outside regex:

preg_match('/word1/i', $string) && preg_match('/word2/i', $string) && preg_match('/word3/i', $string)

or, if your target strings are as simple as word1:

stripos($string, 'word1')!==FALSE && stripos($string, 'word2')!==FALSE && stripos($string, 'word3')!==FALSE
bobince
  • 528,062
  • 107
  • 651
  • 834
  • +1 for multiple regex. People somehow always forget that their source code can contain multiple lines when they think about regex. It's like a world where all software are Perl one-liners. – slebetman Jan 02 '10 at 19:17
  • definitely multiple matches, splitting the problem is often the best way to turn a complex regexp into a trivial solution – Matteo Riva Jan 02 '10 at 20:12
1

I am thinking about a situation in your question that may cause some problem using and case:

this is the situation

words = "abcd","cdef","efgh"

does have to match in the string:

string = "abcdefgh"

maybe you should not using REG.EXP

amir beygi
  • 1,234
  • 8
  • 13
0

If you know the order that the terms will appear in, you could use something like the following:

preg_match("/(word1).*(word2).*(word3)/i", $string);

If the order of terms isn't defined, you will probably be best using 3 separate expressions and checking that they all matched. A single expression is possible but likely complicated.

calvinlough
  • 362
  • 3
  • 13
0
preg_match( "/word1.*word2.*word3)/i");

This works but they must appear in the stated order, you could of course alternate preg_match("/(word1.*word2.*word3|word1.*word3.*word2|word2.*word3.*word1| word2.*word1.*word3|word3.*word2.*word1|word3.*word1.*word2)/i");

But thats pretty herendous and you'd have to be crazy!, would be nicer to just use strpos($haystack,$needle); in a loop, or multiple regex matches.

Paul Creasey
  • 28,321
  • 10
  • 54
  • 90