【问题标题】:how to do a preg_replace on a string in php?如何在php中对字符串执行preg_replace?
【发布时间】:2012-07-29 21:17:55
【问题描述】:

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

$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",结果将是 '*' 等等。

现在$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;

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

【问题讨论】:

    标签: php regex replace preg-replace preg-match


    【解决方案1】:

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

    $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
    

    还有更多。

    【讨论】:

    • 你能把array_map 方法放到public static function cleanStr($str)() 方法中吗?或者$el 是数组还是坏词?
    • $el 是一个单独的数组元素。您可以将逻辑放入一个函数中,但您不是在清理字符串,而是将您的 $bad_words 数组转换为一个对正则表达式更友好的数组,该数组能够替换许多混淆。
    • 以这个字符串为例:i love dictionaries with titles on the top of the page, also shop at fuccillo hyundai! 这里面没有坏词。但是,它会返回 i love ***tionaries with ***les on the top of the page, also shop at ***cillo hyundai! 并且在您的第一个代码块中它应该是 $match[0] 而不是 $match[1]
    • 这很容易解决 - 您需要单词边界。我已经更新了我的答案并修复了$match[0]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    相关资源
    最近更新 更多