替换黑名单数组中的整个单词而不是部分匹配

Replace whole words from blacklist array instead of partial matches

我有一个单词数组

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

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

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

然而,这有效,我过滤的词之一是 'rum',如果我要 post 词 'forum',它将显示为 'fo****'

所以我只需要将单词替换为 **** 如果它与数组中的确切单词匹配,如果我要举一个例子“让我们检查一下论坛,看看是否有人有朗姆酒” , 将是“让我们检查一下论坛,看看是否有人拥有 ****”。

您可以使用带有 \W 的正则表达式来匹配 "non-word" 字符:

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

或者即时调整数组以添加这些位。

在将 haystack 中的每个字符串转换为字符串数组后,您可以使用 preg_replace() 查找带有 beginning/end 字符串标记的针,这样您就可以匹配完整的单词.或者,您可以添加空格并继续使用 str_ireplace(),但如果您的单词是正在检查的字符串中的第一个或最后一个单词,该选项将失败。

添加空格(会漏掉 first/last 个单词,不推荐):

当然你得先修改你的过滤数组。是的,foreach 可以更简单,但我希望这能说明我是什么 doing/why。

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']) );

与其他答案类似,但这在正则表达式中使用 \b 来匹配单词边界(整个单词)。它还会在传递给 preg_replace_callback().

之前即时创建与正则表达式兼容的禁止列表
$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