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).

- 6,843
- 9
- 47
- 62

- 41,293
- 91
- 306
- 570
-
2Related: http://stackoverflow.com/questions/469913/regular-expressions-is-there-an-and-operator – miku Jan 02 '10 at 19:04
4 Answers
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

- 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
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

- 1,234
- 8
- 13
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.

- 362
- 3
- 13
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.

- 28,321
- 10
- 54
- 90