preg_match: and-not 表达式
preg_match: and-not expression
我有一个带换行符的文本,我需要检查它是否有某个词,但没有另一个词。
例如:
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.
如果文本有单词 "lorem" AND "ipsum",无论在哪一行,测试都应该失败。如果文本包含 "lorem" 但任何一行都没有 "ipsum",那么它应该会成功。
我可能会做一些解决方法,并使用条件、explode 和 strpos 函数进行测试。但是我想使用正则表达式规则作为预定义的预设,这样我就可以轻松地扩展功能。
您可以像这样使用正则表达式:
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
}
更新: 你可以在不否定 preg_match 的情况下实现相同的效果,因为 Jonathan Kuhn 在他的评论中指出:
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).
使用这个:
$str = "Lorem my string ipsum";
if (preg_match("/lorem/", $str) && !preg_match("/ipsum/", $str)) {
//code here
}
制作 2 个不同的正则表达式模式比使用一个长正则表达式更容易
$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
}
}
实际上,如果正则表达式有一个 and 运算符会很好,但至少我不知道这样的事情,所以你可以在正则表达式中将它们与 or 运算符匹配,然后使用 array_intersect 来检查。
$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";
}
我建议的正则表达式不需要 !
和 preg_match
,并且只匹配一个多行字符串,没有任何大写或小写的 "lorem" 和 "ipsum",并且作为整个单词:
^(?si)(?!.*?\bipsum\b.*$)(?!.*\blorem\b.*\bipsum\b|\bipsum\b.*\blorem\b.*$).*$
(?si)
设置不区分大小写和单行模式,以便 .
可以匹配换行符并匹配 "Lorem" 和 "lorem"。 \b
s 仅用于匹配整个单词。它还将使具有 ipsum
的字符串失败(第二个条件 (?!.*?\bipsum\b.*$)
设置为处理该字符串)。
$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)) {
...
}
我有一个带换行符的文本,我需要检查它是否有某个词,但没有另一个词。
例如:
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
如果文本有单词 "lorem" AND "ipsum",无论在哪一行,测试都应该失败。如果文本包含 "lorem" 但任何一行都没有 "ipsum",那么它应该会成功。
我可能会做一些解决方法,并使用条件、explode 和 strpos 函数进行测试。但是我想使用正则表达式规则作为预定义的预设,这样我就可以轻松地扩展功能。
您可以像这样使用正则表达式:
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
}
更新: 你可以在不否定 preg_match 的情况下实现相同的效果,因为 Jonathan Kuhn 在他的评论中指出:
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).
使用这个:
$str = "Lorem my string ipsum";
if (preg_match("/lorem/", $str) && !preg_match("/ipsum/", $str)) {
//code here
}
制作 2 个不同的正则表达式模式比使用一个长正则表达式更容易
$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
}
}
实际上,如果正则表达式有一个 and 运算符会很好,但至少我不知道这样的事情,所以你可以在正则表达式中将它们与 or 运算符匹配,然后使用 array_intersect 来检查。
$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";
}
我建议的正则表达式不需要 !
和 preg_match
,并且只匹配一个多行字符串,没有任何大写或小写的 "lorem" 和 "ipsum",并且作为整个单词:
^(?si)(?!.*?\bipsum\b.*$)(?!.*\blorem\b.*\bipsum\b|\bipsum\b.*\blorem\b.*$).*$
(?si)
设置不区分大小写和单行模式,以便 .
可以匹配换行符并匹配 "Lorem" 和 "lorem"。 \b
s 仅用于匹配整个单词。它还将使具有 ipsum
的字符串失败(第二个条件 (?!.*?\bipsum\b.*$)
设置为处理该字符串)。
$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)) {
...
}