首页 / JAVASCRIPT / js实现敏感词过滤算法
js实现敏感词过滤算法
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了js实现敏感词过滤算法,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3562字,纯文字阅读大概需要6分钟。
内容图文
![js实现敏感词过滤算法](/upload/InfoBanner/zyjiaocheng/672/44b5dd603ef14313bfa5df4336cc4e85.jpg)
本文转载于:猿2048网站?https://www.mk2048.com/blog/blog.php?id=hkbk21i00j
大半个月没有更新了,因为最近有点忙(其实是懒)
最近弄了一个用户发表评论的功能,用户上传了评论,再文章下可以看到自己的评论,但作为社会主义接班人,践行社会主义核心价值观,所以给评论敏感词过滤的功能不可少,在网上找了资料,发现已经有非常成熟的解决方案。 常用的方案用这么两种
- 全文搜索,逐个匹配。这种听起来就不够高大上,在数据量大的情况下,会有效率问题,文末有比较
- DFA算法-确定有限状态自动机 附上百科链接 确定有限状态自动机
DFA算法介绍
DFA是一种计算模型,数据源是一个有限个集合,通过当前状态和事件来确定下一个状态,即?状态+事件=下一状态,由此逐步构建一个有向图,其中的节点就是状态,所以在DFA算法中只有查找和判断,没有复杂的计算,从而提高算法效率
参考文章?Java实现敏感词过滤
实现逻辑
构造数据结构
将敏感词转换成树结构,举例敏感词有着这么几个 ['日本鬼子','日本人','日本男人']
,那么数据结构如下(图片引用参考文章)
![js实现敏感词过滤算法 - 文章图片](/upload/getfiles/0001/2021/5/2/20210502101756373.jpg)
每个文字是一个节点,连续的节点组成一个词,日本人
对应的就是中间的那条链,我们可以使用对象或者map来构建树,这里的栗子采用map
构建节点,每个节点中有个状态标识,用来表示当前节点是不是最后一个,每条链路必须要有个终点节点,先来看下构建节点的流程图
![js实现敏感词过滤算法 - 文章图片](/upload/getfiles/0001/2021/5/2/20210502101800951.jpg)
判断逻辑
先从文本的第一个字开始检查,比如你我是日本鬼子
,第一个字 你
,在树的第一层找不到这个节点,那么继续找第二个字,到了日
的时候,第一层节点找到了,那么接着下一层节点中查找本
,同时判断这个节点是不是结尾节点,若是结尾节点,则匹配成功了,反之继续匹配
代码实现
####构造数据结构
/**
* @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实现敏感词过滤算法 - 文章图片](/upload/getfiles/0001/2021/5/2/20210502101801182.jpg)
查找敏感词
/**
* @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实现敏感词过滤算法 - 文章图片](/upload/getfiles/0001/2021/5/2/20210502101801771.jpg)
可直观看出,DFA
的平均耗时是在1ms左右,最大为5ms;indexOf
方式的平均耗时在9ms左右,最大为14ms,所以DFA效率上还是非常明显有优势的。
内容总结
以上是互联网集市为您收集整理的js实现敏感词过滤算法全部内容,希望文章能够帮你解决js实现敏感词过滤算法所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。