js实现敏感词过滤算法及实现逻辑


Posted in Javascript onJuly 24, 2018

最近弄了一个用户发表评论的功能,用户上传了评论,再文章下可以看到自己的评论,但作为社会主义接班人,践行社会主义核心价值观,所以给评论敏感词过滤的功能不可少,在网上找了资料,发现已经有非常成熟的解决方案。 常用的方案用这么两种

1.全文搜索,逐个匹配。这种听起来就不够高大上,在数据量大的情况下,会有效率问题,文末有比较

2.DFA算法-确定有限状态自动机 附上百科链接确定有限状态自动机

DFA算法介绍

DFA是一种计算模型,数据源是一个有限个集合,通过当前状态和事件来确定下一个状态,即 状态+事件=下一状态,由此逐步构建一个有向图,其中的节点就是状态,所以在DFA算法中只有查找和判断,没有复杂的计算,从而提高算法效率

参考文章 Java实现敏感词过滤

实现逻辑

构造数据结构

将敏感词转换成树结构,举例敏感词有着这么几个 ['日本鬼子','日本人','日本男人'] ,那么数据结构如下(图片引用参考文章)

js实现敏感词过滤算法及实现逻辑 

每个文字是一个节点,连续的节点组成一个词, 日本人 对应的就是中间的那条链,我们可以使用对象或者map来构建树,这里的栗子采用 map 构建节点,每个节点中有个状态标识,用来表示当前节点是不是最后一个,每条链路必须要有个终点节点,先来看下构建节点的流程图

js实现敏感词过滤算法及实现逻辑 

判断逻辑

先从文本的第一个字开始检查,比如 你我是日本鬼子 ,第一个字 你 ,在树的第一层找不到这个节点,那么继续找第二个字,到了 日 的时候,第一层节点找到了,那么接着下一层节点中查找 本 ,同时判断这个节点是不是结尾节点,若是结尾节点,则匹配成功了,反之继续匹配

代码实现

####构造数据结构

/**
* @description
* 构造敏感词map
* @private
* @returns
*/
private makeSensitiveMap(sensitiveWordList) {
 // 构造根节点
 const result = new Map();
 for (const word of sensitiveWordList) {
  let map = result;
  for (let i = 0; i < word.length; i++) {
   // 依次获取字
   const char = word.charAt(i);
   // 判断是否存在
   if (map.get(char)) {
    // 获取下一层节点
    map = map.get(char);
   } else {
    // 将当前节点设置为非结尾节点
    if (map.get('laster') === true) {
     map.set('laster', false);
    }
    const item = new Map();
    // 新增节点默认为结尾节点
    item.set('laster', true);
    map.set(char, item);
    map = map.get(char);
   }
  }

 }
 return result;
}

最终map结构如下

js实现敏感词过滤算法及实现逻辑 

查找敏感词

/**
* @description
* 检查敏感词是否存在
* @private
* @param {any} txt
* @param {any} index
* @returns
*/
private checkSensitiveWord(sensitiveMap, txt, index) {
 let currentMap = sensitiveMap;
 let flag = false;
 let wordNum = 0;//记录过滤
 let sensitiveWord = ''; //记录过滤出来的敏感词
 for (let i = index; i < txt.length; i++) {
  const word = txt.charAt(i);
  currentMap = currentMap.get(word);
  if (currentMap) {
   wordNum++;
   sensitiveWord += word;
   if (currentMap.get('laster') === true) {
    // 表示已到词的结尾
    flag = true;
    break;
   }
  } else {
   break;
  }
 }
 // 两字成词
 if (wordNum < 2) {
  flag = false;
 }
 return { flag, sensitiveWord };
}
/**
* @description
* 判断文本中是否存在敏感词
* @param {any} txt
* @returns
*/
public filterSensitiveWord(txt, sensitiveMap) {
 let matchResult = { flag: false, sensitiveWord: '' };
 // 过滤掉除了中文、英文、数字之外的
 const txtTrim = txt.replace(/[^\u4e00-\u9fa5\u0030-\u0039\u0061-\u007a\u0041-\u005a]+/g, '');
 for (let i = 0; i < txtTrim.length; i++) {
  matchResult = checkSensitiveWord(sensitiveMap, txtTrim, i);
  if (matchResult.flag) {
   console.log(`sensitiveWord:${matchResult.sensitiveWord}`);
   break;
  }
 }
 return matchResult;
}

效率

为了看出DFA的效率,我做了个简单的小测试,测试的文本长度为5095个汉字,敏感词词库中有2000个敏感词,比较的算法分别为 DFA算法 和 String原生对象提供的 indexOf API做比较

// 简单的字符串匹配-indexOf
ensitiveWords.forEach((word) => {
 if (ss.indexOf(word) !== -1) {
  console.log(word)
 }
})

分别将两个算法执行100次,得到如下结果

js实现敏感词过滤算法及实现逻辑 

可直观看出, DFA 的平均耗时是在1ms左右,最大为5ms; indexOf 方式的平均耗时在9ms左右,最大为14ms,所以DFA效率上还是非常明显有优势的。

总结

以上所述是小编给大家介绍的js实现敏感词过滤算法及实现逻辑,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
js实现的仿新浪微博完美的时间组件升级版
Dec 20 Javascript
jQuery实现用户注册的表单验证示例
Aug 28 Javascript
处理文本部分内容的TextRange对象应用实例
Jul 29 Javascript
js贪吃蛇游戏实现思路和源码
Apr 14 Javascript
SWFUpload多文件上传及文件个数限制的方法
May 31 Javascript
JavaScript实现点击文本自动定位到下拉框选中操作
Jun 15 Javascript
AngularJS表格详解及示例代码
Aug 17 Javascript
AngularJS  ng-table插件设置排序
Sep 21 Javascript
js print打印网页指定区域内容的简单实例
Nov 01 Javascript
jQuery实现的简单在线计算器功能
May 11 jQuery
mpvue 页面预加载新增preLoad生命周期的两种方式
Oct 17 Javascript
JavaScript判断数据类型有几种方法及区别介绍
Sep 02 Javascript
jQuery实现导航样式布局操作示例【可自定义样式布局】
Jul 24 #jQuery
jQuery实现菜单的显示和隐藏功能示例
Jul 24 #jQuery
Vue三种常用传值示例(父传子、子传父、非父子)
Jul 24 #Javascript
微信小程序实现横向增长表格的方法
Jul 24 #Javascript
vue中使用sessionStorage记住密码功能
Jul 24 #Javascript
Vue-router 中hash模式和history模式的区别
Jul 24 #Javascript
详解Vue的钩子函数(路由导航守卫、keep-alive、生命周期钩子)
Jul 24 #Javascript
You might like
跨浏览器PHP下载文件名中的中文乱码问题解决方法
2015/03/05 PHP
PhpStorm的使用教程(本地运行PHP+远程开发+快捷键)
2020/03/26 PHP
JS 动态获取节点代码innerHTML分析 [IE,FF]
2009/11/30 Javascript
关于include标签导致js路径找不到的问题分析及解决
2013/07/09 Javascript
写JQuery插件的基本知识
2013/11/25 Javascript
IE浏览器中图片onload事件无效的解决方法
2014/04/29 Javascript
javascript实现完美拖拽效果
2015/05/06 Javascript
jQuery实现的仿百度分页足迹效果代码
2015/10/30 Javascript
jQuery实现手机自定义弹出输入框
2016/06/13 Javascript
JS获取IE版本号与HTML设置IE文档模式的方法
2016/10/09 Javascript
利用JS判断字符串是否含有数字与特殊字符的方法小结
2016/11/25 Javascript
jacascript DOM节点——元素节点、属性节点、文本节点
2017/04/18 Javascript
fullPage.js和CSS3实现全屏滚动效果
2017/05/05 Javascript
详解使用vue-cli脚手架初始化Vue项目下的项目结构
2018/03/08 Javascript
jQuery实现获取当前鼠标位置并输出功能示例
2019/01/05 jQuery
jQuery模仿ToDoList实现简单的待办事项列表
2019/12/30 jQuery
JavaScript回调函数callback用法解析
2020/01/14 Javascript
[04:42]5分钟带你了解什么是DOTA2(第一期)
2017/02/07 DOTA
python的绘图工具matplotlib使用实例
2014/07/03 Python
python脚本实现xls(xlsx)转成csv
2016/04/10 Python
使用Python进行AES加密和解密的示例代码
2018/02/02 Python
Python之修改图片像素值的方法
2019/07/03 Python
pytorch实现从本地加载 .pth 格式模型
2020/02/14 Python
pygame用blit()实现动画效果的示例代码
2020/05/28 Python
python实现数字炸弹游戏
2020/07/17 Python
python爬虫快速响应服务器的做法
2020/11/24 Python
adidas美国官网:adidas US
2016/09/21 全球购物
宝拉珍选官方旗舰店:2%水杨酸精华液,收缩毛孔粗大和祛痘
2018/07/01 全球购物
初二物理教学反思
2014/01/29 职场文书
导师工作推荐信范文
2014/05/17 职场文书
庆六一宣传标语
2014/10/08 职场文书
七年级作文之下雨天
2019/12/23 职场文书
oracle连接ODBC sqlserver数据源的详细步骤
2021/07/25 Oracle
Python 中的Sympy详细使用
2021/08/07 Python
关于ObjectUtils.isEmpty() 和 null 的区别
2022/02/28 Java/Android
Oracle配置dblink访问PostgreSQL的操作方法
2022/03/21 PostgreSQL