我试图在堆栈溢出上找到一些代码来覆盖垃圾字过滤器。当我只输入一个垃圾邮件时,该函数可以正常工作,但是当我在它传递的垃圾邮件字之前键入一堆文本时。我检查了来源,我必须遗漏一些东西,有人可以帮忙吗?
代码是:
function strpos_arr($haystack, $needle) {
if(!is_array($needle)) $needle = array($needle);
foreach($needle as $what) {
if(($pos = strpos($haystack, $what))!==false) return $pos;
}
return false;
}
功能我称之为:
if(strpos_arr($text, $bad_words)) {
return false;
} else {
return true;
}
数组只是一个简单的数组,有很多坏词,如下所示:
$bad_words = array(
'bad word 1',
'bad word 2');
链接到原始文章:Using an array as needles in strpos
由于
答案 0 :(得分:2)
首先,看起来你的逻辑是错误的。我想:
if(strpos_arr($text, $bad_words)) {
return false;
} else {
return true;
}
应该是:
if (strpos_arr($text, $bad_words)) {
return TRUE;
} else {
return FALSE;
}
然后,如果找到错误的字词,您将返回$pos
。如果$pos
恰好为零,则下一次检查将失败。除非您需要知道文本中坏词的位置,否则我会将其更改为:
if (($pos = strpos($haystack, $what)) !== FALSE) return TRUE;
答案 1 :(得分:2)
函数strpos_arr
返回字符串中第一个“needle”的位置:
if(($pos = strpos($haystack, $what))!==false) return $pos;
或false
如果文本中没有任何“针”。
这意味着如果文字中有任何不良字,strpos_arr($text, $bad_words)
会返回false
。否则,它返回一个整数,其中包含字符串中第一个坏词的位置。
请注意,当文字以错误字开头时,它会返回0
,相当于false
。这就是为什么当你“只输入一个垃圾邮件时这个功能有效,但是当我在它传递的垃圾邮件之前键入一堆文本时”。
您可以实现一个函数来查找这样的坏词:
function has_bad_word($text, array $bad_words) {
return strpos_arr($text, $bad_words) === false;
}
请注意,strpos_arr
区分大小写,并且当针中的任何字符串是大海捞针中的子字符串时将返回true
,即使它是较大单词的一部分。此功能解决了这两个问题:
function has_bad_word($text, array $bad_words) {
$pregQuotedBadWords = array_map('preg_quote', $bad_words, array('/'));
$badWordsRegex = '/((\s+|^)'
. join('(\s+|$))|((\s+|^)', $pregQuotedBadWords)
. '(\s+|$))/is';
return preg_match($badWordsRegex, $text) > 0;
}