如何实现一个好的粗俗语言过滤器?

224

许多人需要处理用户输入、搜索查询以及可能包含脏话或不良语言的情况。通常需要对此进行过滤。

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

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

有哪些捕捉试图欺骗系统的人的好方法,例如 a$$、azz 或 a55 之类的词汇?

如果您提供PHP的解决方案,则可以获得额外的奖励分。 :)

编辑:回答那些简单避免编程问题的答案:

我认为这种过滤器有其作用,例如当用户可以使用公共图像搜索来查找添加到敏感社区池中的图片时。如果他们可以搜索“阴茎”,那么他们很可能会得到许多图片,是的。如果我们不想要这样的图片,那么防止该词作为搜索词是一个好的看门人,尽管这并非绝对可靠的方法。首先获取单词列表才是真正的问题。

因此,我真正指的是找出单个标记是否肮脏,然后只需禁止它即可。我不会防止像“长颈鹿”这样的完全搞笑的情绪参考。在那里你无能为力。 :)


14
所有的最佳答案都对编程挑战存在主义和失败主义的偏差,这真是可惜。随着“半机械人”计算服务(如“ 机械土耳其 ”)的兴起,以及几乎所有软件都变成社交化的,现在比以往任何时候都更加重要有一个启发式方法来标记内容并将其带到管理员的注意下! - JasonSmith
12
请注意语言上下文,特别是在进行国际化时。我曾试图为我所授课程创建一个名为“Sanal ortamda görselleştirme”的Google小组,这个词汇在土耳其语中的意思是“虚拟媒体中的可视化”。然而,谷歌却因为标题包含“anal”一词而愚蠢地拒绝了它,尽管sanal[tr]=Virtual[en], 谷歌仍然不要脸地指责我使用了亵渎性语言! :D请勿让类似的怪事发生。 - edgerunner
如果您在西班牙语中搜索该单词呢?这样可以绕过Google Images的过滤器(如果您本地化到其他语言)。 - new123456
另一个建议是不要禁止这些词语,而是注册使用它们的用户。如果一个用户/IP使用超过2、3或任何你想要的次数,那么就封锁该用户。虽然不是万无一失,但我认为被封锁并且必须更改用户/IP/两者都要比写“蓬松白兔”而不是“猫咪”更加不方便。此外,用户不知道他们不能使用哪些单词或表达方式,所以他们不能轻易地猜测不同的坏话,因为他们会被禁言。 - Francisco Presencia
2
脏话过滤器不是一个好主意。很难区分有人试图欺骗系统(“Fudge you!”)和有人真正谈论完全适当的事情(“我喜欢巧克力软糖。”)。 - clickbait
显示剩余2条评论
20个回答

185

淫秽过滤器:坏主意,还是极其糟糕的主意?

此外,人们不能忘记Toontown速聊未曾公开的历史,即使使用“安全词白名单”,一个14岁的孩子仍然可以很快地绕过它,用这种话说:“我想把我的长颈鹿塞进你的毛茸茸的小兔子里。”

底线:对于任何您要实现的系统来说,没有什么能代替人工审核(无论是同行审核还是其他方式)。请随意实施一个初步工具来处理驱动式的问题,但对于决心恶意操作者,您必须采用非算法方法。

引入问责制和取消匿名性的系统(例如Stack Overflow)也会有所帮助,特别是为了应对John Gabriel之礼物

您还问到了在哪里可以获取脏话列表以供参考。一个开放源码项目是Dansguardian,请查看其默认脏话列表的源代码。另外还有一个第三方短语列表,您可以下载它作为代理的参考点。

针对问题编辑的编辑:感谢您澄清您正在尝试做什么。在这种情况下,如果您只是想做一个简单的词语过滤器,有两种方法可以做到。一种是创建一个包含所有禁止使用的短语的长正则表达式,并简单地进行正则表达式查找/替换。像这样的正则表达式:

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

使用preg_match()对输入字符串进行完整测试以查找匹配项,

或使用preg_replace()将其替换为空白。

您还可以使用数组加载这些函数,而不是单个长正则表达式,对于长单词列表,这可能更易管理。请参见preg_replace()中的一些示例,了解如何灵活使用数组。

有关其他PHP编程示例,请参见此页面:一个用于屏蔽单词、遮挡敏感词汇中心字母的高级通用类和这个之前的Stack Overflow问题,其中包括一个PHP示例(其中主要有价值的是基于SQL的过滤词方法--如果您认为不需要“leet-speak”补偿器,则可以放弃它)。

你还说:“首先得到单词列表才是真正的问题。”,除了之前的Dansgaurdian链接外,您可能会发现这个458个单词的.zip文件也很有帮助。


7
在你的正则表达式选项周围加上单词边界包装器可以防止出现“clbuttic”错误。 - cjk
关于正则表达式,不要忘记检查单词边界和大小写不敏感性。 - Alix Axel
一个有用的正则表达式修订版:$filterRegex = '/\b(boogers|snot|poop|shucks|argh)\b/i'; 假设您不想阻止像 "it'snot my poop spelling, 'smy fat fingers" 这样的错别字。;) - Bob Davies
所以你不需要关心捕获:b006ers,9oogers,booger5,bo-ogers,boog ers或sɹǝbooq。 - BryanH
1
如果您想从权威人士那里听到“蓬松白兔”故事,现在可以通过播客节目收听:http://socialmediaclarity.tumblr.com/post/70499341079/disneys-hercworld-toontown-and - F. Randall Farmer
显示剩余3条评论

52

虽然我知道这个问题相当老,但这是一个经常发生的问题...

过滤脏话有原因也有必要(参见维基百科条目),但由于上下文准确性的不同,它们通常无法达到100%的准确性。

它取决于你想实现什么——在最基本的层面上,你可能正在尝试涵盖“七个脏字”以及其他一些内容...一些企业需要过滤最基本的脏话:基本的骂人话、URL或甚至个人信息等,但其他企业需要防止非法账户命名(例如 Xbox live)或更多内容...

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

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

而且可能使用多种语言。Shutterstock已经开发了10种语言的基础脏话列表,但这仍然是基础的,并且非常针对他们的“标签”需求。网上还有许多其他列表可用。

我同意被接受的答案,即这不是一门明确定义的科学,而语言是一个不断发展的挑战,但在这个领域,90%的捕获率总比0%好。它完全取决于你的目标——你想实现什么、你拥有的支持水平以及删除不同类型的亵渎性言论的重要程度。

在构建过滤器时,您需要考虑以下元素及其如何与您的项目相关:

  • 单词/短语
  • 首字母缩略词(FOAD/LMFAO等)
  • 假阳性(例如'mishit'、'scunthorpe'和'titsworth')
  • 网址(色情网站是一个明显的目标)
  • 个人信息(电子邮件、地址、电话等-如果适用)
  • 语言选择(通常默认为英语)
  • 内容管理(如何以及是否与用户生成的内容交互以及可以对其进行哪些操作)
  • 您可以轻松构建一个过滤90%以上脏话的过滤器,但永远无法达到100%。这是不可能的。你越想接近100%,就越难...过去曾经构建过一种应对每天处理50万条实时消息的复杂亵渎引擎,我想提供以下建议:

    基本过滤器将涉及:

    • 构建适用的亵渎列表
    • 开发处理亵渎变形的方法

    适度复杂的过滤器将包括(除了基本过滤器):

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

    复杂的过滤器将涉及以下一些内容(除了适度过滤器):

  • 莱文斯坦距离
  • 词干提取
  • 人类管理员协助引导筛选引擎通过示例学习或在没有足够准确匹配的情况下提供指导(自我/不断完善的系统)
  • 也许还需要某种形式的AI引擎

29

我不知道有任何好的库可以做到这一点,但无论你做什么,请确保你的错误方向是允许通过。我曾经遇到过一些系统不允许我将“mpassell”作为用户名,因为它包含“ass”子字符串。那样只会疏远用户!


23
禁止在飞行宇宙游戏中使用“驾驶舱”。 - Shinhan

27

一个粗话过滤系统永远不可能完美,即使程序员非常自信并且紧跟所有裸体相关的发展。

话虽如此,任何“淘气词汇”的列表都有可能与其他任何列表一样好用,因为根本问题是语言理解,这在当前技术下几乎是棘手的。

所以,唯一实际的解决方案是双重的:

  1. 准备经常更新字典
  2. 雇佣人工编辑来更正错误判断(例如,“clbuttic”而不是“classic”)和漏判(哎呀!错过了一个!)

1
仅检测具有空格的单词,后跟句号,不是吗? - David D
2
不行啊,兄弟,那只适用于最琐碎的情况;我们正在处理人类,而他们非常聪明 :) - Steven A. Lowe

26
在我的一次求职面试中,面试我的公司CTO尝试了我用Java编写的一个单词/网络游戏。 在整个牛津英语词典的单词列表中,第一个被猜测出来的单词是什么?
当然,是英语中最恶劣的词汇。
不知何故,我还是得到了这份工作报价,但我随后找到了一个脏话词汇表(不像这个),并编写了一个快速脚本以生成新的字典,而无需查看该列表即可删除所有糟糕的单词。
对于您特定的情况,我认为将搜索与真实单词进行比较听起来是使用此类单词列表的方法。 否则,备选风格/标点符号需要更多的工作,但我怀疑用户不会经常使用它们,因此不必担心。

8
题外话,但什么是最恶心的词?我一直认为是c词或n词,但我想人们认为f词是。 - Jeff
2
"我怀疑用户不会经常使用,因此不会成为问题。" 保持希望。一旦用户遇到过滤器,他们就会努力寻找规避方法。这可能只是将字母替换为数字,或者奇怪的空格位置等简单操作。 - BryanH

14

防止冒犯性用户输入的唯一方法是防止所有用户输入。

如果您坚持允许用户输入并需要进行审核,则应引入人工审核员。


13

15
好的,但它没有捕捉到(。)(。) - Jason Jong
2
小心。CDYNE不再维护此产品。您可以自行决定是否使用,存在风险。 - Sari Rahal
3
测试的URL链接已经损坏。 - Gaurav Sharma

8
注意本地化问题:在一种语言中是脏话的词汇,在另一种语言中可能是完全正常的词汇。
一个当前的例子是:eBay使用字典方法来过滤反馈中的“坏词”。如果您尝试输入“这是一次完美的交易”的德语翻译(“das war eine perfekte Transaktion”),eBay将拒绝该反馈,原因是存在“坏词”。
为什么?因为德语中“was”的意思是“war”,而“war”在eBay的“坏词”字典中。
所以请注意本地化问题。

8
我已经收集了12种语言中2200个不良词汇:英语、阿拉伯语、捷克语、丹麦语、德语、世界语、西班牙语、波斯语、芬兰语、法语、印地语、匈牙利语、意大利语、日语、韩语、荷兰语、挪威语、波兰语、葡萄牙语、俄语、瑞典语、泰语、克林贡语和土耳其语。
您可以选择MySQL dump、JSON、XML或CSV格式进行下载。
请点击https://github.com/turalus/openDB获取更多信息。
我建议您将此SQL代码执行到数据库中,并在用户输入时进行检查。

7
关于您的“欺骗系统”子问题,您可以通过在搜索之前对“坏词”列表和用户输入文本进行规范化来处理。例如,使用一系列正则表达式(或者如果PHP有的话使用tr)将[z$5]转换为“s”,[4@]转换为“a”等,然后将规范化的“坏词”列表与规范化的文本进行比较。请注意,规范化可能会导致额外的误报,尽管我目前想不出任何实际情况。
更大的挑战是想出一些方法,让人们引用“笔比剑更强大”而阻止“p e n i s”。

14
请不要忘记 experts-exchange.com 和 pen-island.com 这两个网站的 URL 曾经没有连字符。 - BryanH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接