Reputation: 327
I have a text with line breaks, and I need to check if it has some word, but doesn't have another.
For example:
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
If the text has word "lorem" AND "ipsum", no matter in wich line, then test should fail. If the text contains "lorem" but does not have "ipsum" on any line, then it should succeed.
I may probably do some workaround, and make tests with conditions, explode and strpos functions. But I want to use regex rules as a predefined presets, so I can easily extend functionality.
Upvotes: 2
Views: 2657
Reputation: 626920
My suggested regex does not require !
with preg_match
, and matches only a multiline string without both "lorem" and "ipsum" in any upper or lower case and as whole words:
^(?si)(?!.*?\bipsum\b.*$)(?!.*\blorem\b.*\bipsum\b|\bipsum\b.*\blorem\b.*$).*$
(?si)
sets case-insensitive and singleline modes so that .
could match a newline and match both "Lorem" and "lorem". \b
s are used to match whole words only. It will also fail a string that has ipsum
(a second condition (?!.*?\bipsum\b.*$)
is set to handle that).
See demo here
$re = "/^(?si)(?!.*?\\bipsum\\b.*$)(?!.*\\blorem\\b.*\\bipsum\\b|\\bipsum\\b.*\\blorem\\b.*$).*$/";
$str = "dolor lorem sit amet, consectetur adipisicing elit, \nsed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
if (preg_match($re, $str, $matches)) {
...
}
Upvotes: 0
Reputation: 98921
$string ="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore ipsum et dolore magna aliqua.";
$string2 ="Lorem dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
loremIpsum ($string );
//string contrains lorem and ipsum
loremIpsum ($string2 );
//string only contrain lorem
function loremIpsum ($string){
if (!preg_match('/(lorem.*?ipsum|ipsum.*?lorem)/sim', $string)) {
if (preg_match('/lorem/sim', $string )) {
# Successful match
echo "string only contain lorem"; // TRUE
}else{
echo "string doesn't contain lorem"; //FALSE
}
}else{
echo "string contrains lorem and ipsum"; //FALSE
}
}
Upvotes: 0
Reputation: 677
Actually it would be good if regex has a and operator but at least i do not know such a thing, so you can match them in regex with or operator and then using array_intersect to check.
$checkArray = array ('lorem', 'ipsum');
$haystack = "lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
$matched = preg_match_all("/lorem|ipsum/i", $haystack, $result, PREG_PATTERN_ORDER);
if ($matched && count($checkArray) == count(array_intersect($checkArray,$result[0]))) {
echo "Gotcha";
}
Upvotes: 0
Reputation: 4199
Use this:
$str = "Lorem my string ipsum";
if (preg_match("/lorem/", $str) && !preg_match("/ipsum/", $str)) {
//code here
}
It is easier to make 2 different regex pattern, than have a single long regex
Upvotes: 1
Reputation: 30995
You can use a regex like this:
lorem[\s\S]*ipsum|ipsum[\s\S]lorem
$re = "/lorem[\\s\\S]*ipsum|ipsum[\\s\\S]lorem/i";
$str = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
if (!preg_match($re, $str, $matches)) {
// your code here
}
Update: you can achieve the same without negating the preg_match as Jonathan Kuhn pointed in his comment:
Also, if you wanted to make this work without needing to negate the preg_match you could wrap it in a zero-width negative group like:
^(?!lorem[\s\S]*ipsum|ipsum[\s\S]lorem).*$
. This will match the entire string where both words don't exist. Demo (shows as not matching until you remove one of the words).
Upvotes: 1