替换黑名单数组中的整个单词而不是部分匹配
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
我有一个单词数组
$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