0

我有一些简单的代码可以进行预匹配:

$bad_words = array('dic', 'tit', 'fuc',); //for this example i replaced the bad words

for($i = 0; $i < sizeof($bad_words); $i++)
{
    if(preg_match("/$bad_words[$i]/", $str, $matches))
    {
        $rep = str_pad('', strlen($bad_words[$i]), '*');
        $str = str_replace($bad_words[$i], $rep, $str);
    }
}
echo $str;

所以,如果$str"dic"结果将是' * '等等。

现在有一个小问题 if $str == f.u.c。解决方案可能是使用:

$pattern = '~f(.*)u(.*)c(.*)~i';
$replacement = '***';
$foo =  preg_replace($pattern, $replacement, $str);

在这种情况下,无论如何我都会得到***。我的问题是将所有这些代码放在一起。

我试过了:

$pattern = '~f(.*)u(.*)c(.*)~i';
$replacement = 'fuc';
$fuc =  preg_replace($pattern, $replacement, $str);

$bad_words = array('dic', 'tit', $fuc,); 

for($i = 0; $i < sizeof($bad_words); $i++)
{
    if(preg_match("/$bad_words[$i]/", $str, $matches))
    {
        $rep = str_pad('', strlen($bad_words[$i]), '*');
            $str = str_replace($bad_words[$i], $rep, $str);
    }
}
echo $str;

这个想法是,然后我将它放在数组$fucfuc,然后数组完成它的工作,但这似乎不起作用。

4

1 回答 1

3

首先,您可以使用一个(动态生成的)正则表达式来完成所有坏词替换,如下所示:

$bad_words = array('dic', 'tit', 'fuc',);

$str = preg_replace_callback("/\b(?:" . implode( '|', $bad_words) . ")\b/", 
    function( $match) {
        return str_repeat( '*', strlen( $match[0])); 
}, $str);

现在,您遇到了人们在单词之间添加句点的问题,您可以使用另一个正则表达式搜索并替换它们。但是,您必须记住.匹配正则表达式中的任何字符,并且必须进行转义(使用preg_quote()反斜杠或反斜杠)。

$bad_words = array_map( function( $el) { 
    return implode( '\.', str_split( $el));
}, $bad_words);

这将创建一个$bad_words类似于以下内容的数组:

array(
    'd\.i\.c',
    't\.i\.t',
    'f\.u\.c'
)

现在,您可以$bad_words像上面一样使用这个新数组来替换这些混淆的数组。

提示:你可以让这个array_map()调用“更好”,因为它可以更聪明地捕捉更多的混淆。例如,如果你想捕捉一个用句点、空格字符或逗号分隔的坏词,你可以这样做:

$bad_words = array_map( function( $el) { 
    return implode( '(?:\.|\s|,)', str_split( $el));
}, $bad_words);

现在,如果您将该混淆组设为可选,您会发现更多的坏词:

$bad_words = array_map( function( $el) { 
    return implode( '(?:\.|\s|,)?', str_split( $el));
}, $bad_words);

现在,坏词应该匹配:

f.u.c
f,u.c
f u c 
fu c
f.uc

还有很多。

于 2012-08-01T01:38:59.147 回答