如何实现良好的脏话过滤器?

发布于 2024-07-08 18:00:28 字数 555 浏览 14 评论 0原文

我们中的许多人需要处理用户输入、搜索查询以及输入文本可能包含脏话或不良语言的情况。 通常这需要被过滤掉。

在哪里可以找到各种语言和方言的脏话列表?

是否有可用于包含良好列表的源的 API? 或者也许有一个 API 只是简单地说“是的,这是干净的”或“不,这是肮脏的”,并带有一些参数?

有哪些好方法可以用来抓捕试图欺骗系统的人,例如 a$$、azz 或 a55?

如果您提供 PHP 解决方案,将获得加分。 :)

编辑:对简单地避免程序化问题的答案的回应:

我认为这种过滤器有一席之地,例如,用户可以使用公共图像搜索来查找获得的图片添加到敏感社区池。 如果他们可以搜索“阴茎”,那么他们可能会得到很多照片,是的。 如果我们不想要那个图片,那么阻止这个词作为搜索词是一个很好的把关人,尽管不可否认,这不是一个万无一失的方法。 首先获取单词列表才是真正的问题。

所以我真正指的是一种方法来确定单个令牌是否脏,然后简单地禁止它。 我不会费心去阻止像完全搞笑的“长颈长颈鹿”这样的情绪。 你在那里无能为力。 :)

Many of us need to deal with user input, search queries, and situations where the input text can potentially contain profanity or undesirable language. Oftentimes this needs to be filtered out.

Where can one find a good list of swear words in various languages and dialects?

Are there APIs available to sources that contain good lists? Or maybe an API that simply says "yes this is clean" or "no this is dirty" with some parameters?

What are some good methods for catching folks trying to trick the system, like a$$, azz, or a55?

Bonus points if you offer solutions for PHP. :)

Edit: Response to answers that say simply avoid the programmatic issue:

I think there is a place for this kind of filter when, for instance, a user can use public image search to find pictures that get added to a sensitive community pool. If they can search for "penis", then they will likely get many pictures of, yep. If we don't want pictures of that, then preventing the word as a search term is a good gatekeeper, though admittedly not a foolproof method. Getting the list of words in the first place is the real question.

So I'm really referring to a way to figure out of a single token is dirty or not and then simply disallow it. I'd not bother preventing a sentiment like the totally hilarious "long necked giraffe" reference. Nothing you can do there. :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

傲性难收 2024-07-15 18:00:29

虽然我知道这个问题相当老了,但这是一个常见的问题......

对脏话过滤器既有原因也有明显的需求(请参阅维基百科条目),但由于非常明显的原因,它们常常达不到 100% 准确; 上下文准确性

这(完全)取决于您想要实现的目标 - 最基本的是,您可能试图涵盖“七个脏东西一些企业需要过滤最基本的脏话:基本的脏话、URL甚至个人信息等等,但其他企业则需要防止非法帐户命名(Xbox live就是一个例子) )或更多...

用户生成的内容不仅包含潜在的脏话,还可能包含对以下内容的冒犯性引用:

  • 性行为、性取向
  • 宗教
  • 、种族
  • 等...

并且可能以多种语言呈现。 Shutterstock 开发了 10 种语言的基本脏词列表,日期,但它仍然是基本的,并且非常面向他们的“标记”需求。 网络上还有许多其他列表。

我同意公认的答案,即这不是一门明确的科学,因为语言是一项不断发展的挑战,但 90% 的捕获率优于 0%。 这完全取决于您的目标 - 您想要实现的目标、您获得的支持程度以及消除不同类型的脏话的重要性。

在构建过滤器时,您需要考虑以下元素以及它们与您的项目的关系:

  • 单词/短语
  • 首字母缩略词(FOAD/LMFAO 等)
  • 误报(单词、地点和名称,例如“mishit”、“scunthorpe”和“titsworth”)
  • URL(色情网站是明显的目标)
  • 个人信息(电子邮件、地址、电话等 - 如果适用)
  • 语言选择(默认情况下通常为英语)
  • 审核(如何(如果有的话)与用户生成的内容进行交互以及可以用它做什么)

您可以轻松构建一个捕获 90% 以上的脏话的脏话过滤器,但您永远不会达到100%。 这是不可能的。 你越接近 100%,就越难...过去构建了一个复杂的脏话引擎,每天处理超过 500K 条实时消息,我提供以下建议:

基本的过滤器将涉及:

  • 建立适用的脏话列表
  • 开发处理脏话派生的方法

中等复杂的过滤器将涉及:(除了基本过滤器之外):

  • 使用复杂的模式匹配处理扩展派生(使用高级正则表达式)
  • 处理 Leetspeak (l33t)
  • 处理 误报

复杂的过滤器将涉及以下许多内容(除了中等过滤器之外):

Whilst I know that this question is fairly old, but it's a commonly occurring question...

There is both a reason and a distinct need for profanity filters (see Wikipedia entry here), but they often fall short of being 100% accurate for very distinct reasons; Context and accuracy.

It depends (wholly) on what you're trying to achieve - at it's most basic, you're probably trying to cover the "seven dirty words" and then some... Some businesses need to filter the most basic of profanity: basic swear words, URLs or even personal information and so on, but others need to prevent illicit account naming (Xbox live is an example) or far more...

User generated content doesn't just contain potential swear words, it can also contain offensive references to:

  • Sexual acts
  • Sexual orientation
  • Religion
  • Ethnicity
  • Etc...

And potentially, in multiple languages. Shutterstock has developed basic dirty-words lists in 10 languages to date, but it's still basic and very much oriented towards their 'tagging' needs. There are a number of other lists available on the web.

I agree with the accepted answer that it's not a defined science and as language is a continually evolving challenge but one where a 90% catch rate is better than 0%. It depends purely on your goals - what you're trying to achieve, the level of support you have and how important it is to remove profanities of different types.

In building a filter, you need to consider the following elements and how they relate to your project:

  • Words/phrases
  • Acronyms (FOAD/LMFAO etc)
  • False positives (words, places and names like 'mishit', 'scunthorpe' and 'titsworth')
  • URLs (porn sites are an obvious target)
  • Personal information (email, address, phone etc - if applicable)
  • Language choice (usually English by default)
  • Moderation (how, if at all, you can interact with user generated content and what you can do with it)

You can easily build a profanity filter that captures 90%+ of profanities, but you'll never hit 100%. It's just not possible. The closer you want to get to 100%, the harder it becomes... Having built a complex profanity engine in the past that dealt with more than 500K realtime messages per day, I'd offer the following advice:

A basic filter would involve:

  • Building a list of applicable profanities
  • Developing a method of dealing with derivations of profanities

A moderately complex filer would involve, (In addition to a basic filter):

  • Using complex pattern matching to deal with extended derivations (using advanced regex)
  • Dealing with Leetspeak (l33t)
  • Dealing with false positives

A complex filter would involve a number of the following (In addition to a moderate filter):

  • Whitelists and blacklists
  • Naive bayesian inference filtering of phrases/terms
  • Soundex functions (where a word sounds like another)
  • Levenshtein distance
  • Stemming
  • Human moderators to help guide a filtering engine to learn by example or where matches aren't accurate enough without guidance (a self/continually-improving system)
  • Perhaps some form of AI engine
忆梦 2024-07-15 18:00:29

我不知道有什么好的库可以做到这一点,但无论你做什么,请确保你在让东西通过的方向上犯了错误。 我处理过不允许我使用“mpassell”作为用户名的系统,因为它包含“ass”作为子字符串。 这是疏远用户的好方法!

I don't know of any good libraries for this, but whatever you do, make sure that you err in the direction of letting stuff through. I've dealt with systems that wouldn't allow me to use "mpassell" as a username, because it contains "ass" as a substring. That's a great way to alienate users!

﹏半生如梦愿梦如真 2024-07-15 18:00:29

脏话过滤系统永远不会是完美的,即使程序员有信心并跟上所有裸体开发的步伐

,任何“顽皮的话”列表都可能像任何其他列表一样执行,因为根本问题是语言理解对于当前的技术来说非常棘手

,因此,唯一实用的解决方案是双重的:

  1. 准备好经常更新你的词典,
  2. 聘请人工编辑来纠正误报(例如“clbuttic”而不是“classic”)和漏报(哎呀!错过了一个!)

a profanity filtering system will never be perfect, even if the programmer is cocksure and keeps abreast of all nude developments

that said, any list of 'naughty words' is likely to perform as well as any other list, since the underlying problem is language understanding which is pretty much intractable with current technology

so, the only practical solution is twofold:

  1. be prepared to update your dictionary frequently
  2. hire a human editor to correct false positives (e.g. "clbuttic" instead of "classic") and false negatives (oops! missed one!)
云醉月微眠 2024-07-15 18:00:29

在我的一次求职面试中,面试我的公司 CTO 尝试了我用 Java 编写的一款文字/网页游戏。 在整个牛津英语词典的单词列表中,第一个被猜出的单词是什么?

当然是英语中最粗俗的词了。

不知何故,我仍然得到了工作机会,但随后我找到了一份脏话列表(与不同)这个)并编写了一个快速脚本来生成一本新词典,其中没有所有坏词(甚至无需查看列表)。

对于您的特定情况,我认为将搜索与真实单词进行比较听起来像是使用这样的单词列表的方法。 替代样式/标点符号需要更多的工作,但我怀疑用户是否经常使用它会成为一个问题。

During a job interview of mine, the company CTO who was interviewing me tried out a word/web game I wrote in Java. Out of a word list of the entire Oxford English dictionary, what was the first word that came up to be guessed?

Of course, the most foul word in the English language.

Somehow, I still got the job offer, but I then tracked down a profanity word list (not unlike this one) and wrote a quick script to generate a new dictionary without all of the bad words (without even having to look at the list).

For your particular case, I think comparing the search to real words sounds like the way to go with a word list like that. The alternative styles/punctuation require a bit more work, but I doubt users will use that often enough to be an issue.

明媚殇 2024-07-15 18:00:29

阻止攻击性用户输入的唯一方法是阻止所有用户输入。

如果您坚持允许用户输入并需要审核,请纳入人工审核员。

The only way to prevent offensive user input is to prevent all user input.

If you insist on allowing user input and need moderation, then incorporate human moderators.

千纸鹤 2024-07-15 18:00:29

注意本地化问题:在一种语言中是脏话的词在另一种语言中可能是完全正常的词。

当前的一个例子是:eBay 使用字典方法从反馈中过滤“坏词”。 如果您尝试输入“这是一次完美的交易”(“das war eine perfekte Transaktion”)的德文翻译,eBay 会因用词不当而拒绝该反馈。

为什么? 因为德语中的“was”是“war”,而“war”在eBay词典中是“坏词”。

所以要小心本地化问题。

Beware of localization issues: what is a swearword in one language might be a perfectly normal word in another.

One current example of this: ebay uses a dictionary approach to filter "bad words" from feedback. If you try to enter the german translation of "this was a perfect transaction" ("das war eine perfekte Transaktion"), ebay will reject the feedback due to bad words.

Why? Because the german word for "was" is "war", and "war" is in ebay dictionary of "bad words".

So beware of localisation issues.

情场扛把子 2024-07-15 18:00:29

我收集了 12 种语言的 2200 个脏词:en、ar、cs、da、de、eo、es、fa、fi、fr、hi、hu、it、ja、ko、nl、no、pl、pt、ru、sv 、th、tlh、tr、zh。

提供 MySQL 转储、JSON、XML 或 CSV 选项。

https://github.com/turalus/openDB

我建议您在数据库中执行此 SQL并在每次用户输入内容时进行检查。

I collected 2200 bad words in 12 languages: en, ar, cs, da, de, eo, es, fa, fi, fr, hi, hu, it, ja, ko, nl, no, pl, pt, ru, sv, th, tlh, tr, zh.

MySQL dump, JSON, XML or CSV options are available.

https://github.com/turalus/openDB

I'd suggest you to execute this SQL into your DB and check everytime when user inputs something.

难得心□动 2024-07-15 18:00:29

关于“欺骗系统”子问题,您可以通过在搜索之前标准化“坏词”列表和用户输入的文本来处理该问题。 例如,使用一系列正则表达式(或 tr,如果 PHP 有的话)将 [z$5] 转换为“s”,[4@] > 到“a”等,然后将规范化的“坏词”列表与规范化的文本进行比较。 请注意,标准化可能会导致额外的误报,尽管我目前无法想到任何实际案例。

更大的挑战是想出一些东西,让人们引用“笔比剑更强大”,同时阻止“阴茎”。

Regarding your "trick the system" subquestion, you can handle that by normalizing both the "bad word" list and the user-entered text before doing your search. e.g., Use a series of regexes (or tr if PHP has it) to convert [z$5] to "s", [4@] to "a", etc., then compare the normalized "bad word" list against the normalized text. Note that the normalization could potentially lead to additional false positives, although I can't think of any actual cases at the moment.

The larger challenge is to come up with something that will let people quote "The pen is mightier than the sword" while blocking "p e n i s".

酒与心事 2024-07-15 18:00:29

如果你可以做一些像 Digg/Stackoverflow 这样的事情,用户可以投票/标记淫秽内容……就这样做吧。

然后你需要做的就是审查“顽皮”用户,如果他们违反规则,就阻止他们。

If you can do something like Digg/Stackoverflow where the users can downvote/mark obscene content... do so.

Then all you need to do is review the "naughty" users, and block them if they break the rules.

深海少女心 2024-07-15 18:00:29

我来晚了一点,但我有一个可能对某些阅读本文的人有用的解决方案。 它是用 javascript 而不是 php 编写的,但这是有充分理由的。

完全公开,我写了这个插件......

无论如何。

我采用的方法是允许用户“选择加入”他们的脏话过滤。 基本上默认情况下允许使用脏话,但如果我的用户不想阅读,他们也不必这样做。 这也有助于解决“l33t sp3@k”问题。

这个概念是一个简单的 插件,通过注入如果客户端的帐户启用了脏话过滤,则服务器。 从那里开始,只有几行简单的线条就可以消除脏话。

这是演示页面
https://chaseflorell.github.io/jQuery.ProfanityFilter/demo/

<div id="foo">
    ass will fail but password will not
</div>

<script>
    // code:
    $('#foo').profanityFilter({
        customSwears: ['ass']
    });
</script>

结果

*** 会失败,但密码不会

I'm a little late to the party, but I have a solution that might work for some who read this. It's in javascript instead of php, but there's a valid reason for it.

Full disclosure, I wrote this plugin...

Anyways.

The approach I've gone with is to allow a user to "Opt-In" to their profanity filtering. Basically profanity will be allowed by default, but if my users don't want to read it, they don't have to. This also helps with the "l33t sp3@k" issue.

The concept is a simple plugin that gets injected by the server if the client's account is enabling profanity filtering. From there, it's just a couple simple lines that blot out the swears.

Here's the demo page
https://chaseflorell.github.io/jQuery.ProfanityFilter/demo/

<div id="foo">
    ass will fail but password will not
</div>

<script>
    // code:
    $('#foo').profanityFilter({
        customSwears: ['ass']
    });
</script>

result

*** will fail but password will not

北城半夏 2024-07-15 18:00:29

同样是在游戏后期,但做了一些研究并偶然发现了这里。 正如其他人提到的,如果它是自动化的,那几乎是不可能的,但如果你的设计/需求在某些情况下(但不是一直)可以涉及人类交互来检查它是否亵渎,你可以考虑机器学习。 https://learn。 microsoft.com/en-us/azure/cognitive-services/content-moderator/text-moderation-api#profanity 是我目前的选择,原因有多种:

  • 支持许多本地化
  • 他们不断更新数据库,所以我不必跟上最新的俚语或语言(维护问题)
  • 当可能性很高(即 90% 或更高)时,您可以实用地否认它
  • 您可以观察导致可能会或可能不会的标志的类别亵渎,并且可以让人审查它以教导它是否亵渎。

根据我的需要,它是基于公众友好的商业服务(好吧,视频游戏),其他用户可能/将会看到用户名,但设计要求它必须经过亵渎过滤器以拒绝攻击性用户名。 令人遗憾的是,经典的“clbuttic”问题很可能会发生,因为用户名通常是单个单词(最多 N 个字符),有时是多个单词连接...同样,微软的认知服务不会将“Assist”标记为文本。 HasProfanity=true 但可能会将其中一个类别的概率标记为高。

正如OP询问的那样,“a$$”怎么样,这是我通过过滤器传递它时的结果: 在此处输入图像描述,如您所见,它已确定它不是亵渎的,但它的概率很高确实如此,因此标记为审查建议(人际互动)。

当概率很高时,我可以返回“对不起,该名字已经被占用”(即使它没有被占用),这样如果我们不想的话,这样就不会冒犯反审查人员或其他什么东西集成人工审核,或返回“您的用户名已通知直播部门,您可以等待您的用户名审核通过或选择其他用户名”。 或者无论如何...

顺便说一句,对于我的目的来说,这项服务的成本/价格相当低(用户名多久更改一次?),但同样,对于 OP 来说,设计可能需要更密集的查询,并且可能并不理想支付/订阅 ML 服务,或者无法进行人工审核/交互。 这一切都取决于设计......但如果设计确实符合要求,也许这可以是 OP 的解决方案。

如果有兴趣,我可以在以后的评论中列出缺点。

Also late in the game, but doing some researches and stumbled across here. As others have mentioned, it's just almost close to impossible if it was automated, but if your design/requirement can involve in some cases (but not all the time) human interactions to review whether it is profane or not, you may consider ML. https://learn.microsoft.com/en-us/azure/cognitive-services/content-moderator/text-moderation-api#profanity is my current choice right now for multiple reasons:

  • Supports many localization
  • They keep updating the database, so I don't have to keep up with latest slangs or languages (maintenance issue)
  • When there is a high probability (I.e. 90% or more) you can just deny it pragmatically
  • You can observe for category which causes a flag that may or may not be profanity, and can have somebody review it to teach that it is or isn't profane.

For my need, it was/is based on public-friendly commercial service (OK, videogames) which other users may/will see the username, but the design requires that it has to go through profanity filter to reject offensive username. The sad part about this is the classic "clbuttic" issue will most likely occur since usernames are usually single word (up to N characters) of sometimes multiple words concatenated... Again, Microsoft's cognitive service will not flag "Assist" as Text.HasProfanity=true but may flag one of the categories probability to be high.

As the OP inquires, what about "a$$", here's a result when I passed it through the filter:enter image description here, as you can see, it has determined it's not profane, but it has high probability that it is, so flags as recommendations of reviewing (human interactions).

When probability is high, I can either return back "I'm sorry, that name is already taken" (even if it isn't) so that it is less offensive to anti-censorship persons or something, if we don't want to integrate human review, or return "Your username have been notified to the live operation department, you may wait for your username to be reviewed and approved or chose another username". Or whatever...

By the way, the cost/price for this service is quite low for my purpose (how often does the username gets changed?), but again, for OP maybe the design demands more intensive queries and may not be ideal to pay/subscribe for ML-services, or cannot have human-review/interactions. It all depends on the design... But if design does fit the bill, perhaps this can be OP's solution.

If interested, I can list the cons in the comment in the future.

默嘫て 2024-07-15 18:00:29

一旦你有了一个好的 MYSQL 表,其中包含一些你想要过滤的坏词(我从这个线程中的一个链接开始),你可以做这样的事情:

$errors = array();  //Initialize error array (I use this with all my PHP form validations)

$SCREENNAME = mysql_real_escape_string($_POST['SCREENNAME']); //Escape the input data to prevent SQL injection when you query the profanity table.

$ProfanityCheckString = strtoupper($SCREENNAME); //Make the input string uppercase (so that 'BaDwOrD' is the same as 'BADWORD').  All your values in the profanity table will need to be UPPERCASE for this to work.

$ProfanityCheckString = preg_replace('/[_-]/','',$ProfanityCheckString); //I allow alphanumeric, underscores, and dashes...nothing else (I control this with PHP form validation).  Pull out non-alphanumeric characters so 'B-A-D-W-O-R-D' shows up as 'BADWORD'.

$ProfanityCheckString = preg_replace('/1/','I',$ProfanityCheckString); //Replace common numeric representations of letters so '84DW0RD' shows up as 'BADWORD'.

$ProfanityCheckString = preg_replace('/3/','E',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/4/','A',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/5/','S',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/6/','G',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/7/','T',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/8/','B',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/0/','O',$ProfanityCheckString); //Replace ZERO's with O's (Capital letter o's).

$ProfanityCheckString = preg_replace('/Z/','S',$ProfanityCheckString); //Replace Z's with S's, another common substitution.  Make sure you replace Z's with S's in your profanity database for this to work properly.  Same with all the numbers too--having S3X7 in your database won't work, since this code would render that string as 'SEXY'.  The profanity table should have the "rendered" version of the bad words.

$CheckProfanity = mysql_query("SELECT * FROM DATABASE.TABLE p WHERE p.WORD = '".$ProfanityCheckString."'");
if(mysql_num_rows($CheckProfanity) > 0) {$errors[] = 'Please select another Screen Name.';} //Check your profanity table for the scrubbed input.  You could get real crazy using LIKE and wildcards, but I only want a simple profanity filter.

if (count($errors) > 0) {foreach($errors as $error) {$errorString .= "<span class='PHPError'>$error</span><br /><br />";} echo $errorString;} //Echo any PHP errors that come out of the validation, including any profanity flagging.


//You can also use these lines to troubleshoot.
//echo $ProfanityCheckString;
//echo "<br />";
//echo mysql_error();
//echo "<br />";

我确信有一种更有效的方法来完成所有这些替换,但我不够聪明,无法弄清楚(这似乎工作正常,尽管效率低下)。

我认为您应该错误地允许用户注册,并根据需要使用人工过滤并添加到您的脏话表中。 尽管这一切都取决于误报(好的词被标记为坏词)与误报(坏词被通过)的成本。 这最终应该决定你的过滤策略是激进还是保守。

如果您想使用通配符,我也会非常小心,因为它们有时会比您预期的更加繁重。

Once you have a good MYSQL table of some bad words you want to filter (I started with one of the links in this thread), you can do something like this:

$errors = array();  //Initialize error array (I use this with all my PHP form validations)

$SCREENNAME = mysql_real_escape_string($_POST['SCREENNAME']); //Escape the input data to prevent SQL injection when you query the profanity table.

$ProfanityCheckString = strtoupper($SCREENNAME); //Make the input string uppercase (so that 'BaDwOrD' is the same as 'BADWORD').  All your values in the profanity table will need to be UPPERCASE for this to work.

$ProfanityCheckString = preg_replace('/[_-]/','',$ProfanityCheckString); //I allow alphanumeric, underscores, and dashes...nothing else (I control this with PHP form validation).  Pull out non-alphanumeric characters so 'B-A-D-W-O-R-D' shows up as 'BADWORD'.

$ProfanityCheckString = preg_replace('/1/','I',$ProfanityCheckString); //Replace common numeric representations of letters so '84DW0RD' shows up as 'BADWORD'.

$ProfanityCheckString = preg_replace('/3/','E',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/4/','A',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/5/','S',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/6/','G',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/7/','T',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/8/','B',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/0/','O',$ProfanityCheckString); //Replace ZERO's with O's (Capital letter o's).

$ProfanityCheckString = preg_replace('/Z/','S',$ProfanityCheckString); //Replace Z's with S's, another common substitution.  Make sure you replace Z's with S's in your profanity database for this to work properly.  Same with all the numbers too--having S3X7 in your database won't work, since this code would render that string as 'SEXY'.  The profanity table should have the "rendered" version of the bad words.

$CheckProfanity = mysql_query("SELECT * FROM DATABASE.TABLE p WHERE p.WORD = '".$ProfanityCheckString."'");
if(mysql_num_rows($CheckProfanity) > 0) {$errors[] = 'Please select another Screen Name.';} //Check your profanity table for the scrubbed input.  You could get real crazy using LIKE and wildcards, but I only want a simple profanity filter.

if (count($errors) > 0) {foreach($errors as $error) {$errorString .= "<span class='PHPError'>$error</span><br /><br />";} echo $errorString;} //Echo any PHP errors that come out of the validation, including any profanity flagging.


//You can also use these lines to troubleshoot.
//echo $ProfanityCheckString;
//echo "<br />";
//echo mysql_error();
//echo "<br />";

I'm sure there is a more efficient way to do all those replacements, but I'm not smart enough to figure it out (and this seems to work okay, albeit inefficiently).

I believe that you should err on the side of allowing users to register, and use humans to filter and add to your profanity table as required. Though it all depends on the cost of a false positive (okay word flagged as bad) versus a false negative (bad word gets through). That should ultimately govern how aggressive or conservative you are in your filtering strategy.

I would also be very careful if you want to use wildcards, since they can sometimes behave more onerously than you intend.

淡笑忘祈一世凡恋 2024-07-15 18:00:29

我同意 HanClinto 在本次讨论中较高的帖子。 我通常使用正则表达式来字符串匹配输入文本。 这是徒劳的,因为,就像您最初提到的那样,您必须在“阻止”列表中明确说明网络上流行的每种写作技巧形式。

顺便说一句,虽然其他人正在争论审查制度的道德问题,但我必须同意,某种形式在网络上是必要的。 有些人只是喜欢发布粗俗内容,因为它可能会立即冒犯很多人,并且完全不需要作者考虑。

谢谢你的想法。

汉克林顿统治!

I agree with HanClinto's post higher up in this discussion. I generally use regular expressions to string-match input text. And this is a vain effort, as, like you originally mentioned you have to explicitly account for every trick form of writing popular on the net in your "blocked" list.

On a side note, while others are debating the ethics of censorship, I must agree that some form is necessary on the web. Some people simply enjoy posting vulgarity because it can be instantly offensive to a large body of people, and requires absolutely no thought on the author's part.

Thank you for the ideas.

HanClinto rules!

丘比特射中我 2024-07-15 18:00:29

坦白说,我会让他们把“欺骗系统”这几个字去掉,然后禁止他们,这只是我的想法。 但它也使编程变得更简单。

我要做的就是实现一个正则表达式过滤器,如下所示: /[\s]dooby (doo?)[\s]/i 或者该单词在其他单词上添加前缀, /[ \s]doob(er|ed|est)[\s]/。 这些将阻止过滤像 assuged 这样的单词,这是完全有效的,但也需要了解其他变体,并在您学习新的过滤器时更新实际的过滤器。 显然,这些都是示例,但您必须自己决定如何做。

我不会把我知道的所有单词都打出来,除非我真的不想知道它们。

Frankly, I'd let them get the "trick the system" words out and ban them instead, which is just me. But it also makes the programming simpler.

What I'd do is implement a regex filter like so: /[\s]dooby (doo?)[\s]/i or it the word is prefixed on others, /[\s]doob(er|ed|est)[\s]/. These would prevent filtering words like assuaged, which is perfectly valid, but would also require knowledge of the other variants and updating the actual filter if you learn a new one. Obviously these are all examples, but you'd have to decide how to do it yourself.

I'm not about to type out all the words I know, not when I don't actually want to know them.

公布 2024-07-15 18:00:29

不。 它只会导致问题。 我对脏话过滤器的一次不愉快的个人经历是,有一次我因为提到我“要过桥去汉考克几个小时”或类似的事情而被踢/禁止进入 IRC 频道。

Don't. It just leads to problems. One clbuttic personal experience I have with profanity filters is the time where I was kick/banned from an IRC channel for mentioning that I was "heading over the bridge to Hancock for a couple hours" or something to that effect.

李白 2024-07-15 18:00:29

我同意这个主题的徒劳性,但如果你必须有一个过滤器,请查看 Ning 的 Boxwood

Boxwood 是一个 PHP 扩展,用于快速替换一段文本中的多个单词。 它支持区分大小写和不区分大小写的匹配。 它要求其操作的文本编码为 UTF-8。

另请参阅此博客文章了解更多详细信息:

使用 Boxwood,您可以将搜索词列表设置为任意长度 - 搜索和替换算法不会因要查找的单词列表中的单词越多而变慢。 它的工作原理是构建所有搜索词的特里树,然后仅扫描一次主题文本,遍历特里树的元素并将它们与文本中的字符进行比较。 它支持 US-ASCII 和 UTF-8、区分大小写或不区分大小写的匹配,并具有一些以英语为中心的单词边界检查逻辑。

I agree with the futility of the subject, but if you have to have a filter, check out Ning's Boxwood:

Boxwood is a PHP extension for fast replacement of multiple words in a piece of text. It supports case-sensitive and case-insensitive matching. It requires that the text it operates on be encoded as UTF-8.

Also see this blog post for more details:

With Boxwood, you can have your list of search terms be as long as you like -- the search and replace algorithm doesn't get slower with more words on the list of words to look for. It works by building a trie of all the search terms and then scans your subject text just once, walking down elements of the trie and comparing them to characters in your text. It supports US-ASCII and UTF-8, case-sensitive or insensitive matching, and has some English-centric word boundary checking logic.

黄昏下泛黄的笔记 2024-07-15 18:00:29

我的结论是,为了创建一个好的脏话过滤器,我们需要 3 个主要组件,或者至少这是我要做的。 它们是:

  1. 过滤器:根据黑名单、字典或类似内容进行验证的后台服务。
  2. 不允许匿名帐户
  3. 报告滥用行为

一个额外的好处是,将以某种方式奖励那些提供准确的滥用行为举报者的人,并惩罚违规者,例如暂停他们的帐户。

I concluded, in order to create a good profanity filter we need 3 main components, or at least it is what I am going to do. These they are:

  1. The filter: a background service that verify against a blacklist, dictionary or something like that.
  2. Not allow anonymous account
  3. Report abuse

A bonus, it will be to reward somehow those who contribute with accurate abuse reporters and punish the offender, e.g. suspend their accounts.

好听的两个字的网名 2024-07-15 18:00:29

不。

因为:

  • Clbuttic
  • 脏话不是天哪,邪恶的
  • 脏话无法有效定义
  • 大多数人很可能不喜欢被“保护”免受亵渎

编辑:虽然我同意评论者所说的“审查制度是错误的”,但这不是这个答案的本质。

Don't.

Because:

  • Clbuttic
  • Profanity is not OMG EVIL
  • Profanity cannot be effectively defined
  • Most people quite probably don't appreciate being "protected" from profanity

Edit: While I agree with the commenter who said "censorship is wrong", that is not the nature of this answer.

梦归所梦 2024-07-15 18:00:28

淫秽过滤器:坏主意,或令人难以置信的坏交流想法?

另外,人们不能忘记卡通城 SpeedChat 不为人知的历史,即使使用“安全词白名单”也会导致一名 14 岁的孩子迅速绕过它:
“我想把我的长颈长颈鹿粘在你毛茸茸的白色兔子身上。”

底线:最终,对于您实施的任何系统,绝对无法替代人工审核(无论是同行审核还是其他审核) 。 随意实施一个基本的工具来摆脱路过的,但对于坚定的巨魔,你绝对必须有一个非基于算法的方法。

一个消除匿名性并引入问责制的系统(Stack Overflow 做得很好)也很有帮助,特别是为了帮助打击 John Gabriel 的礼物

您还询问在哪里可以获取脏话列表来帮助您入门 - 一个值得查看的开源项目是 Dansguardian - 查看其默认脏话列表的源代码。 您还可以为代理下载一个额外的第三方短语列表,这可能会很有帮助给你点。

针对问题编辑进行编辑:感谢您对您要执行的操作的说明。 在这种情况下,如果您只是尝试进行简单的单词过滤器,则有两种方法可以实现。 一种是创建一个长正则表达式,其中包含您想要审查的所有禁止短语,然后仅用它进行正则表达式查找/替换。 正则表达式如下:

$filterRegex = "(boogers|snot|poop|shucks|argh)"

并使用 preg_match() 在输入字符串上运行它来批量测试命中,

或者preg_replace() 将它们清空。

您还可以使用数组而不是单个长正则表达式来加载这些函数,并且对于长单词列表,它可能更易于管理。 请参阅 preg_replace() 以获取一些有关如何灵活使用数组的好示例。

有关其他 PHP 编程示例,请参阅此页面,了解 word 的一些高级泛型类过滤出 * 被审查单词的中心字母,以及这个 上一个 Stack Overflow 问题一个 PHP 示例(其中主要有价值的部分是基于 SQL 的过滤词方法——如果您觉得没有必要,可以省掉 leet-speak 补偿器)。

您还添加了:“首先获取单词列表才是真正的问题。”——除了之前的一些 Dansgaurdian 链接之外,您可能会发现 这个方便的 .zip 458 个单词很有帮助。

Obscenity Filters: Bad Idea, or Incredibly Intercoursing Bad Idea?

Also, one can't forget The Untold History of Toontown's SpeedChat, where even using a "safe-word whitelist" resulted in a 14-year-old quickly circumventing it with:
"I want to stick my long-necked Giraffe up your fluffy white bunny."

Bottom line: Ultimately, for any system that you implement, there is absolutely no substitute for human review (whether peer or otherwise). Feel free to implement a rudimentary tool to get rid of the drive-by's, but for the determined troll, you absolutely must have a non-algorithm-based approach.

A system that removes anonymity and introduces accountability (something that Stack Overflow does well) is helpful also, particularly in order to help combat John Gabriel's G.I.F.T.

You also asked where you can get profanity lists to get you started -- one open-source project to check out is Dansguardian -- check out the source code for their default profanity lists. There is also an additional third party Phrase List that you can download for the proxy that may be a helpful gleaning point for you.

Edit in response to the question edit: Thanks for the clarification on what you're trying to do. In that case, if you're just trying to do a simple word filter, there are two ways you can do it. One is to create a single long regexp with all of the banned phrases that you want to censor, and merely do a regex find/replace with it. A regex like:

$filterRegex = "(boogers|snot|poop|shucks|argh)"

and run it on your input string using preg_match() to wholesale test for a hit,

or preg_replace() to blank them out.

You can also load those functions up with arrays rather than a single long regex, and for long word lists, it may be more manageable. See the preg_replace() for some good examples as to how arrays can be used flexibly.

For additional PHP programming examples, see this page for a somewhat advanced generic class for word filtering that *'s out the center letters from censored words, and this previous Stack Overflow question that also has a PHP example (the main valuable part in there is the SQL-based filtered word approach -- the leet-speak compensator can be dispensed with if you find it unnecessary).

You also added: "Getting the list of words in the first place is the real question." -- in addition to some of the previous Dansgaurdian links, you may find this handy .zip of 458 words to be helpful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文