假设“xyza”是一个坏词。我正在使用以下方法来取代令人反感的词 -
$text = str_replace("x***","(Offensive words detected & removed!)",$text);
此代码将xyza替换为“(检测到攻击性词语&删除!)”。
但问题是“案例”如果有人输入XYZA我的代码无法检测到它。怎么解决?
答案 0 :(得分:11)
无论您做什么,用户都会找到绕过您的过滤器的方法。他们将使用unicode字符(аss
,例如,使用西里尔语а
并且不会被任何正则表达式解决方案捕获。他们将使用空格,美元符号,星号,无论你还没有抓到它们。
如果家庭友好对您的申请至关重要,请让某人在内容上线之前对其进行审核。否则,添加一个标记功能,以便其他人可以标记令人反感的内容。更好的是,使用某种机器学习或贝叶斯过滤器来自动标记可能令人反感的帖子并让人类手动检查它们。人们比计算机更好地阅读人类语言。
答案 1 :(得分:3)
白名单/黑名单的问题是 - 正如其他用户所指出的那样 - 您的用户将优先考虑寻找满足您的过滤器的方法,而不是将您的网站用于其目的,无论可能是什么。
一种方法是使用Google为其“你喜欢什么?”网站创建的无证亵渎API。如果您收到true
的回复,则只需向用户提供一条消息,说明由于检测到亵渎而无法提交其帖子。
您可以按如下方式处理:
<?php
if (isset($_POST['submit'])) {
$result = json_decode(file_get_contents(sprintf('http://www.wdyl.com/profanity?q=%s', urlencode($_POST['comments']))));
if ($result->response == true) {
// profanity detected
}
else {
// save comments to database as normal
}
}
答案 2 :(得分:2)
其他答案和评论说,编程不是解决此问题的最佳解决方案。我同意他们。这些答案应移至Moderators - Stack Exchange或Webmasters - Stack Exchange。
由于这是stackoverflow,我的答案将基于计算机编程。
如果您想使用str_replace,请执行以下操作。 为了这篇文章,由于有些人被实际的cusswords冒犯了,让我们假装这些是坏词: 'fug','schnitt','dam'。
$text = str_ireplace(" fug ","(Offensive words detected & removed!)",$text);
注意,它是str_ireplace
而不是str_replace
。 i 用于“不区分大小写”。
但这将错误地匹配“fuggedaboudit”,例如。
如果你想做一份更可靠的工作,你需要使用正则表达式。
$bad_text = "Fug dis schnitt, because a schnitter never dam wins a fuggin schnitting darn";
$hit_words = array("fug","schnitt","dam"); // these words are 'hits' that we need to replace. hit words...
array_walk($hit_words, function(&$value, $key) { // this prepares the regex, requires PHP 5.3+ I think.
$value = '~\b' . preg_quote( $value ,'~') . '\b~i'; // \b means word boundary, like space, line-break, period, dash, and many others. Prevends "refudgee" from being matched when searching for "fudge"
});
/*print_r($bad_words);*/
$good_words = array("fudge","shoot","dang");
$good_text = preg_replace($hit_words,$good_words,$bad_text); // does all search/replace actions at once
echo '<br />' . $good_text . '<br />';
这将立即进行所有搜索/替换。这两个数组应包含相同数量的元素,匹配搜索和替换术语。它不会匹配部分单词,只会匹配整个单词。当然,坚定的客户会找到让他们在你的网站上咒骂的方法。但它会阻止懒惰的cussers。
我决定添加一些链接到显然使用编程的网站,以便通过删除亵渎性来进行首次运行。当我遇到它们时,我会添加更多。除了雅虎:
1。)Dell.com - 将匹配的单词替换为<profanity deleted>
。
http://en.community.dell.com/support-forums/peripherals/f/3529/t/19502072.aspx
2。)超级计算机Watson显然出现了诅咒问题。你如何区分诅咒和俚语?显然,研究人员决定将其全部清除是如此困难。但是他们可能只是使用了一个诅咒词汇列表(我想说,精确匹配是正则表达式的一个子集)并且禁止使用它们。无论如何,这就是它在现实生活中的运作方式。 Watson develops a profanity problem
商务应用中的3。)Content Compliance section Gmail自定义设置:
- 添加描述您要在每封邮件中搜索的内容的表达式
醇>
使用的“Expresssions”可以有多种类型,包括“高级内容匹配”,除其他外,它允许您选择“匹配类型”选项,与您在Excel过滤器中的选项非常相似:启动with,Ends with,Contains,Not contains,Equals,Is Empty,所有这些都可能使用正则表达式。但是等等,还有更多:匹配正则表达式,不匹配正则表达式,匹配任何单词,匹配所有单词。因此,强大的Google为其业务用户实施了正则表达式过滤选项。当正则表达式被认为无效时,为什么会这样做?因为它实际上足够有效。这是一个简单,快速的编程解决方案,只有当人们一心想要绕过它时才会失败。
除了那个列表,我想知道是否还有其他人注意到除去亵渎和过滤掉垃圾邮件之间的相似性。很明显,正则表达式在两个竞技场中都有用,但是通过死记硬背得知“所有正则表达都不好”的人会在任何问题的答案中,如果甚至提到正则表达式的话。 尝试谷歌搜索“垃圾邮件过滤器如何工作”。你会得到像这个覆盖垃圾邮件刺客的结果: http://www.seas.upenn.edu/cets/answers/spamblock-filter.html
我确信使用正则表达式的另一个例子是通过Amazon.com的亚马逊商城进行通信。您会收到常用电子邮件地址的电子邮件。所以,当然,在回复卖家时,您的电子邮件程序将包含各种发件人信息,例如您的电子邮件地址,cc电子邮件地址以及您输入正文的任何信息。但亚马逊网站将这些消除“为了您的保护”。我可以找到解决这个正则表达式的方法吗?可能,但它会比它的价值更麻烦,因此在某种程度上是有效的。他们还会将这些电子邮件保留2年,大概是因为如果有任何欺诈行为,人们可以通过这些电子邮件。
SpamAssassin还会查看邮件的主题和正文,以查看当邮件“看起来像垃圾邮件”时人们注意到的相同类型的内容。它搜索“伟哥”,“立即购买”,“最低价格”,“点击此处”等字符串。它还会查找华丽的HTML,如大字体,闪烁文本,鲜艳的颜色等。
没有提到正则表达式,但我确定它正在使用中。
答案 3 :(得分:0)
使用str_ireplace函数表示不区分大小写的str_replace()
$text = str_ireplace("flip","(Offensive words detected & removed!)", $text);
答案 4 :(得分:0)
您应该使用正则表达式替换,并且需要将i
标记添加到正则表达式的末尾,以便无论大小写都搜索您的文本。所以..
$text = preg_replace("/xyza/i","(Offensive words detected & removed!)", $text);
如果您不需要复杂的正则表达式规则,也可以使用 str_ireplace
。
$text = str_ireplace("xyza","(Offensive words detected & removed!)", $text);
事实上,后者是首选方式,因为它比正则表达式操作更快。来自PHP文档:
如果您不需要花哨的替换规则,通常应该使用此函数而不是preg_replace()和i修饰符。
但是,正如评论者指出的那样,如果您要替换的子字符串作为另一个非冒犯性词语的一部分出现,简单的字符串/正则表达式替换可能会破坏您的字符串。为此,您可以在正则表达式中使用单词边界,也可以只替换那些不能成为其他字符串一部分的单词(例如单词xyza
)。
答案 5 :(得分:0)
使用&#39; str_ireplace&#39;替换任何区分大小写的字符串 可能,这会对你有帮助
$text = 'contains offensive_word .... so on';
$array = array(
'offensive_word' => '****',
'offensive_word2' => '****',
'offensive_word3' => '****',
//.....
);
$text = str_ireplace(array_keys($array),array_values($array), $text);
echo $text;