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 相关文章推荐
JavaScript的面向对象(一)
Nov 09 Javascript
与jquery serializeArray()一起使用的函数,主要来方便提交表单
Jan 31 Javascript
jquery中的过滤操作详细解析
Dec 02 Javascript
JS delegate与live浅析
Dec 21 Javascript
JQuery判断radio是否选中并获取选中值的示例代码
Oct 17 Javascript
AngularJS基础知识笔记之过滤器
May 10 Javascript
Spring mvc 接收json对象
Dec 10 Javascript
jQuery 监控键盘一段时间没输入
Apr 22 Javascript
AngularJS指令详解及示例代码
Aug 16 Javascript
Bootstrap中定制LESS-颜色及导航条(推荐)
Nov 21 Javascript
详解Angular的双向数据绑定(MV-VM)
Dec 26 Javascript
ejsExcel模板在Vue.js项目中的实际运用
Jan 27 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
用Zend Encode编写开发PHP程序
2006/10/09 PHP
php+mysql 实现身份验证代码
2010/03/24 PHP
Netbeans 8.2将支持PHP7 更精彩
2016/06/13 PHP
PHP基于pdo的数据库操作类【可支持mysql、sqlserver及oracle】
2018/05/21 PHP
PHP 枚举类型的管理与设计知识点总结
2020/02/13 PHP
简单的无缝滚动程序-仅几行代码
2007/05/08 Javascript
js/jquery去掉空格,回车,换行示例代码
2013/11/05 Javascript
javascript电商网站抢购倒计时效果实现
2015/11/19 Javascript
在AngularJS中如何使用谷歌地图把当前位置显示出来
2016/01/25 Javascript
浅谈EasyUI常用控件的禁用方法
2016/11/09 Javascript
利用jquery实现验证输入的是否是数字、小数,包含保留几位小数
2016/12/07 Javascript
input获取焦点时底部菜单被顶上来问题的解决办法
2017/01/24 Javascript
vue-lazyload图片延迟加载插件的实例讲解
2018/02/09 Javascript
基于vue v-for 循环复选框-默认勾选第一个的实现方法
2018/03/03 Javascript
浅谈Vue2.0中v-for迭代语法的变化(key、index)
2018/03/06 Javascript
微信小程序实现文件、图片上传功能
2020/08/18 Javascript
通过JQuery,JQueryUI和Jsplumb实现拖拽模块
2019/06/18 jQuery
react组件基本用法示例小结
2020/04/27 Javascript
JSONObject与JSONArray使用方法解析
2020/09/28 Javascript
编程语言Python的发展史
2014/09/26 Python
Python基于正则表达式实现文件内容替换的方法
2017/08/30 Python
python 图像处理画一个正弦函数代码实例
2019/09/10 Python
jenkins配置python脚本定时任务过程图解
2019/10/29 Python
Python tkinter布局与按钮间距设置方式
2020/03/04 Python
python实现遍历文件夹图片并重命名
2020/03/23 Python
SQL面试题
2013/04/30 面试题
2014年百日安全生产活动总结
2014/05/04 职场文书
小学优秀学生评语
2014/12/29 职场文书
爱情保证书
2015/01/17 职场文书
2015年爱国卫生月活动总结
2015/03/26 职场文书
企业财务经理岗位职责
2015/04/08 职场文书
幼儿教师三分钟演讲稿
2019/06/21 职场文书
python实现腾讯滑块验证码识别
2021/04/27 Python
python实现自定义日志的具体方法
2021/05/28 Python
Win11安装受阻怎么办? Windows11安装问题与解决方案汇总
2021/11/21 数码科技
DIY胆机必读:各国电子管评价
2022/04/06 无线电