审查可能包含标记的不恰当单词的最佳方法是什么?

时间:2013-01-08 13:57:57

标签: php regex filter spam

我运行一个包含数百万个包含HTML的用户生成帖子的大型网站。其中一些帖子包含我的广告客户不希望在旁边做广告的敏感词语。我宁愿审查“坏”字,而不是删除这些帖子。我还需要保留标记,因为让用户标记他们的帖子是该网站的一个主要特征。

我目前正在使用搜索并替换为str_ireplace(),但我们的作者已经变得聪明并正在做事(下面)通过我的原始过滤器。我可以删除标签并检测不合适的单词,但我正在寻找一种替换单词的方法,同时保持标记不变。

示例:

成功审查:

input:  "<p>Mary is a bitch.</p>"
output: "<p>Mary is a *****.</p>" 

未成功审查:

input:          "<p>Mary is a <strong>b</strong>itch.</p>"
failed output:  "<p>Mary is a <strong>b</strong>itch.</p>" 
desired output: "<p>Mary is a <strong>*</strong>****.</p>"

4 个答案:

答案 0 :(得分:2)

我的建议是使用其他方法来阻止这种情况,因为这非常困难。

来自this amusing piece by Jeff Atwood

关于尝试这样做会产生什么样的'clbuttic'问题:

  

猥亵过滤是一个持久的,甚至是永恒的问题。我怀疑通过代码单独解决这个特殊问题是不可能的。但似乎一些公司和开发商无法停止在那个风车上倾斜。这意味着在你搬到斯肯索普之前,你可能需要三思而行。

答案 1 :(得分:1)

只是为了好玩,这是一种快速而肮脏的方式:

$badWords = array('bitch', 'jerk');
$input = '<p>Mary is a <strong>b</strong>itch. </p>';

$arr = explode(' ', $input);

foreach($arr as $key => $word)
{
    $word = str_replace('.', '', strip_tags($word));
    if(in_array($word, $badWords))
    {
        $arr[$key] = '*****';
    }
}

$output = implode(' ', $arr);
echo $output;

输出

<p>Mary is a ***** </p>

以上内容将文字拆分为单词,并对每个单词应用strip_tags(),这样就不会影响整个内容。

正如评论所指出的那样,仍有很多方法可以解决这个问题。你永远不会得到一个完美的解决方案,可以处理他们投入的一切 - 你需要创造一些接近人工智能的东西。我认为最好的真正解决方案是在整个帖子上strip_tags()并搜索坏词,然后如果找到,则标记帖子以供主持人注意。或者只是简单地建立一个包含活跃版主的报告系统。

答案 2 :(得分:0)

你可以从“坏词”列表开始,检查标签清理字符串(即通过strip_tags()过滤“坏词”。 然后你可以通过一系列可能的单字母变更来迭代每个坏词,例如S=>5, 1=>L, 0=>O等。

答案 3 :(得分:0)

你将有一个非常艰难的时间以你的方式实现这一点,但我的建议是不要用星号改变单词,而是拒绝发布并让用户知道原因。原因如下:

  1. 简化您的搜索。如果您的算法只需检查文本中是否存在某种形式的错误字词,那么您可以strip_tags文本并搜索您的字词。如果您尝试用星号替换它,则不能strip_tags,因为您需要保留原始文本的先前条件。
  2. 这是人们所期望的。人们期望的是他们的文字被修改而没有通知他们。你可能会更好地向人们发送一条消息,上面写着“此帖包含不恰当的字词/文字”
  3. 如果您坚持用星号替换而不是将用户发回,则需要编写一个基本的逐字符解析器,忽略HTML标记并从中构造单词。