需求

敏感词检查是一个很常见的需求,在做用户输入功能时,如果不对敏感词进行检查,不仅影响平台内容的质量,可能还因此违反法律法规直接被封。敏感词是动态的,不同时机敏感不同,用户还会千方百计的使用谐音、拼音等避开检查,所以需要实时的更新。及时修改规则。

分析

最好的办法当然是人工审核,效果最好,但是人工审核成本太高了,要是内容少还好,一多根本审核不过来,影响用户发布内容,用户跑完了。

所以一般都是通过机器检查并且不断的根据实际情况完善检测机制。

机器检测也可以通过机器学习的方法不过不在本文的讨论范围内。

先建立一个敏感词库,对用户输入的文本逐个比较检查是否包含敏感词库里的敏感词。

敏感词库建立比较简单,就建立一个表保存敏感词,提供CURD操作即可。敏感词库可以网上找,而且不同的业务需要的敏感词是不一样的,一般网上找一版之后再进行人工筛查后不断的完善即可。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XhrJzHoF-1668919959859)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3fdd756e521943ccac03312e77ed0d41~tplv-k3u1fbpfcp-watermark.image?)]

这样敏感词检测问题就转化成字符串匹配的问题。假设敏感词库里有一千条敏感词,那么每次都需要进行一千次匹配,比如下面代码。

public static void main(String[] args) {List<String> sensitiveWordList = new ArrayList<>();sensitiveWordList.add("今天");sensitiveWordList.add("明天");sensitiveWordList.add("后天");String word = "今天去上班,明天也要去上班,后天不用去上班";for (String s : sensitiveWordList) {if(sensitiveWord(word, s)){System.out.println("存在敏感词:"+ s);}}
}public static boolean sensitiveWord(String word, String sensitiveWord){if(sensitiveWord.length() == 0){return true;}if(word.length()  < sensitiveWord.length() ){return false;}for (int i = 0; i < word.length(); i++) {//首字母相等继续匹配下一个字母if(word.charAt(i) == sensitiveWord.charAt(0)){if(sensitiveWord(word.substring(i+1), sensitiveWord.substring(1))){return true;}//否则匹配下一个字母开始}else if(sensitiveWord(word.substring(i+1), sensitiveWord)){return true;}}return false;
}

输出结果为

存在敏感词:今天
存在敏感词:明天
存在敏感词:后天

整体思路也是比较直观的,和人工去匹配的思维是一样的,代码中先遍历输入句子是否存在这个字,如果不存在就比较下一个字符,如果存在就进入子循环检查下一个字符是否是,如果是就存在,如果不是再回到原来的地方继续寻找这个字符,不断重复此步骤直到末尾。

人工检查也是这样子找的,这样的代码很多循环会显得很笨重。一点都不优雅而且随着敏感词的增多,会越来越慢。如果上万个敏感词,那么每次输入都要进行上万次循环(晕)

有什么办法进行优化呢?

仔细比较会发现有一些重复的比较。比如,如果存在敏感词颜色电影颜色小视频颜色图片,去检查句子网站中如果存在颜色电影将会被依法查封那么颜色这两个字会被检查三次,重复计算了三次。

存在重复的工作那么就存在优化的空间。如何做让它只进行一次检查后面共用结果呢?

既然是因为三个敏感词都存在颜色才会重复计算,那么是否可以将它们三个归类,先检查颜色再检查颜色后面是否是电影小视频图片呢,这样检查颜色后,如果后面存在电影小视频图片说明存在敏感词。

进一步想,颜色电影可以拆成颜色电影那么也可以拆成颜``色``电``影四个字,这样后面如果新加一个颜如玉这样的敏感词又可以共用字,减少的匹配次数。美哉。

因为匹配单词是从前面按顺序往后所有字符都匹配才能算成功匹配,所以只有相同前缀的词可以共用前缀复用匹配。

如果说所有敏感词都不存在公共前缀那么就没法通过这个方法优化了。

这就是成了著名前缀树
[208. 实现 Trie (前缀树)](https://leetcode.cn/problems/implement-trie-prefix-tree/)

所以将所有敏感词构建一棵前缀树,之后将用户输入的内容进行检查即可。

public static void main(String[] args) {List<String> sensitiveWordList = new ArrayList<>();sensitiveWordList.add("今天");sensitiveWordList.add("明天");sensitiveWordList.add("后天");String word = "今天去上班,明天也要去上班,后天不用去上班";//初始化一棵前缀树Trie trie = new Trie();for (String s : sensitiveWordList) {trie.insert(s);}System.out.println(trie.sensitiveWord(word));}
static class Trie {//通过map保存子树private Map<Character, Trie> children ;private boolean isEnd;public Trie() {children = new HashMap<>();isEnd = false;}//将敏感词插入到前缀树中public void insert(String word) {Trie node = this;for (int i = 0; i < word.length(); i++) {char ch = word.charAt(i);Trie childrenNode = node.children.get(ch);if(childrenNode == null){node.children.put(ch, new Trie());}node = node.children.get(ch);}node.isEnd = true;}//检查一个单词的开头是否存在铭感词private boolean prefixSensitiveWord(String word, int start) {Trie node = this;for (int i = start; i < word.length(); i++) {char ch = word.charAt(i);Trie childrenNode = node.children.get(ch);if(childrenNode == null){//说明后面没有匹配的了break;}else{//说明存在一个敏感词匹配了if(childrenNode.isEnd){return true;}}node = childrenNode;}return node.isEnd;}//检查一个单词是否存在铭感词private boolean sensitiveWord(String word) {//不断向前移动检查for (int i = 0; i < word.length(); i++) {if(prefixSensitiveWord(word, i)){return true;}}return false;}
}

后续

只是通过简单的敏感词匹配判断存在敏感词也存在一些缺陷,比如一台独立的服务器,是理论上是合规的但是其中含有台又有独所以可能被判定含有敏感词。中文博大精深,可能换个读音表达一个意思,懂的都懂,但是机器不懂。牛点的可以通过人工智能的手段,训练一个专门识别敏感词的模型,提高识别率。但是语言博大精深,像在王者荣耀这种大游戏也照样能不带一点脏话骂人[狗头dog],可见要通过机器准确的进行敏感词检测难度之大,所以敏感词的检测只是一个简单的初步检查,真要花心思发布违规内容很难拦下或者说准确的拦截敏感词的成本是很高的。

一般再通过设计一些用户投诉机制,发布敏感词惩罚机制等进一步提高用户发敏感词的成本,想办法让用户不发,问题解决不了就解决搞出问题的人,嘿嘿。

一个敏感词检查功能是怎么来的相关推荐

  1. 【前缀树】写一个敏感词过滤器

    1.什么是敏感词过滤 这其实是一个很常见的功能,随处可见以至于你可能都没关注过,基本上在有评论的地方都会有它的身影. 举例来说,你打游戏和别人对喷的时候,是不是一些脏话发不出去哈哈,这些词汇会用*** ...

  2. java敏感词屏蔽器,“敏感词过滤”功能设置

    "敏感词过滤"功能设置 "敏感词过滤"是指对互联网发布的言论和文章中含有的敏感词进行过滤.敏感词经过在互联网的传播和扩散会影响社会的稳定和用户的使用.云锁的&q ...

  3. 简单实现敏感词过滤功能

    现在基本所有的网页都存在敏感词过滤的功能,最近开发项目的时候,需要一个敏感词过滤的功能,参考了很多博客,便对此做了总结和自己的开发代码. 一.构建敏感词库 读取文件数据,并保存到HashMap中,构建 ...

  4. java dfa 敏感词_java利用DFA算法实现敏感词过滤功能

    前言 敏感词过滤应该是不用给大家过多的解释吧?讲白了就是你在项目中输入某些字(比如输入xxoo相关的文字时)时要能检 测出来,很多项目中都会有一个敏感词管理模块,在敏感词管理模块中你可以加入敏感词,然 ...

  5. 如何设计一个敏感词匹配系统?

    ▲ 点击上方"分布式实验室"关注公众号 回复"1"抽取纸质技术书 谛听系统是vivo的内容审核平台,保障了vivo各互联网产品持续健康的发展.谛听支持审核多种内 ...

  6. 1.设计一个敏感词过滤程序

    1.设计一个敏感词过滤程序 WordFilter类 属性:数组类型[]存放敏感词 设计一个方法,调用这个方法(传参,可能会包含敏感词的字符串),返回过滤后的新的字符串public static Str ...

  7. .设计一个敏感词过滤程序

    1.设计一个敏感词过滤程序     WordFilter类         属性:数组类型[]存放敏感词 设计一个方法,调用这个方法(传参,可能会包含敏感词的字符串),返回过滤后的新的字符串      ...

  8. JS实现敏感词过滤功能

    当用户在多行输入框中输入,禁止输入的单词或字时,不让它显示出来,以*代替,详细代码如下: <!DOCTYPE html> <html lang="en"> ...

  9. kong 自建一个具有健康检查功能的http/tcp负载均衡器,配置流量权重,自动/手动目标健康,流量统一认证、鉴权、限流限速、修正,监控、日志等功能

    全栈工程师开发手册 (作者:栾鹏) 架构系列文章 Kong 目前kong的最新版为2.2,官方git在https://github.com/Kong/kong,下面是一个kong的简单结构 kong的 ...

最新文章

  1. linux下的qt缺少iostream,c – iostream:没有这样的文件或目录
  2. tryLock尝试获取锁
  3. JDK源码解析之 java.lang.ThreadLocal
  4. IE环境下判断IE版本的语句...[if lte IE 6]……[endif][if lte IE 7]……[endif]
  5. C#中调用Windows API的要点 .
  6. linux安装 soapui_SOAP测试工具-SoapUI For Linux下载V5.2.1免费版-西西软件下载
  7. centos使用迅雷远程下载
  8. 移动wifi宝显示无服务器,优游宝4G随身WiFi解决方案 云SIM技术无需插卡
  9. 100m光纤测速多少正常_100m光纤测速多少正常 所以100M宽带最大下载速度
  10. 智能家居蓝海 如何才能破解“外热内冷”的尴尬?
  11. AS使用Viewbinding出现Could not find method buildFeatures() for arguments报错
  12. 天龙八部雁门关外的故事
  13. wp教程-wp详细教程-免费wordpress模板主题搭建教程
  14. Nat. Mach. Intell. | 快速的蛋白质结构从头预测
  15. xDSL:数字用户线路技术(DSL、IDSL、ADSL、HDSL、SDSL、VDSL、G.Lite)--网络大典
  16. 论文投稿指南——中文核心期刊推荐(生物科学 2)
  17. 基于c++的扑克牌游戏
  18. 服务器无盘网卡设置,安装无盘时各种网卡最佳设置
  19. java重命名sheet失败_错误1004重命名工作表
  20. 使用idea创建servlet程序(idea:2021.2)

热门文章

  1. 【Python】Python实现简易中国象棋(非客户端)
  2. 云服务器与独立服务器哪个比较好?
  3. 使用宏命令撤销EXCEL工作表保护
  4. xp_CAPTCHA V4.1(瞎跑-白嫖版)安装
  5. Flask——创建表单模型类与模板使用
  6. 四句话看懂等保2.0测评结果
  7. 修改mysql的名字_修改mysql的数据库名字
  8. 区块链的商业价值理解
  9. Python—分支程序
  10. 深度报告 | AI新职位“人工智能训练师”