PHP过滤确切词而不是部分词

时间:2019-09-16 21:11:18

标签: php arrays filter word

我有一个单词数组

   $banned_names = array('about','access','account');

实际数组很长,其中包含坏词,因此有可能违反任何规则,我刚刚添加了一个示例,我遇到的问题是以下

$title = str_ireplace($filterWords, '****', $dn1['title']);

这有效,但是我过滤的单词之一是“ rum”,如果我要张贴“ forum”一词,它将显示为“ fo ****”

因此,如果我要匹配数组中的确切单词,我只需要用****替换单词,如果我要举一个例子“让我们检查论坛并查看是否有人朗姆酒”,将是“让我们检查论坛,看看是否有人有****”。

预先感谢

3 个答案:

答案 0 :(得分:3)

您可以将正则表达式与\W配合使用以匹配“非单词”字符:

var_dump(preg_match('/\Wrum\W/i', 'the forum thing')); // returns 0 i.e. doesn't match
var_dump(preg_match('/\Wrum\W/i', 'the rum thing'));   // returns 1 i.e. matches

preg_replace()方法像str_replace()一样采用一个过滤器数组,但是您必须调整列表以在两边都包括模式定界符和\W。您可以将完整模式静态存储在列表中:

$banlist = ['/\Wabout\W/i','/\Waccess\W/i', ... ];
preg_replace($banlist, '****', $text);

或动态调整数组以添加这些位。

答案 1 :(得分:2)

与其他答案类似,但这在正则表达式中使用\b来匹配单词边界(整个单词)。在传递给preg_replace_callback()之前,它还会动态创建与regex兼容的禁止列表。

$dn1['title'] = 'access forum'; 

$banned_names = array('about','access','account','rum');
$banned_list = array_map(function($r) { return '/\b' . preg_quote($r, '/') . '\b/'; }, $banned_names); 

$title = preg_replace_callback($banned_list, function($m) { 
   return $m[0][0].str_repeat('*', strlen($m[0])-1);
}, $dn1['title']);

echo $title; //a***** forum

答案 2 :(得分:1)

在将干草堆中的每个字符串转换为字符串数组之后,您可以使用preg_replace()查找带有字符串标签开头/结尾的针,这样您就可以匹配完整的单词。另外,您可以添加空格并继续使用str_ireplace(),但是如果您的单词是被检查字符串中的第一个或最后一个单词,则该选项将失败。

添加空格(将遗漏第一个/最后一个单词,不建议)

当然,您必须首先修改过滤数组。是的,foreach可能会更简单,但是我希望这可以弄清楚我在做什么/为什么这么做。

foreach($filterWords as $key => $value){
    $filterWords[$key] = " ".$value." ";
}
str_ireplace ( $filterWords, "****", $dn1['title'] );

或 分解长字符串(推荐):

foreach($filterWords as $key => $value){
    $filterWords[$key] = "/^".$value."$/i"; //add regex for beginning/end of string value
}
preg_replace ( $filterWords, "****", explode(" ", $dn1['title']) );