一、前言

开发中经常要处理用户一些文字的提交,所以涉及到了敏感词过滤的功能,参考资料中DFA有穷状态机算法的实现,创建有向图。完成了对敏感词、广告词的过滤,而且效率较好,所以分享一下。

具体实现:

1、匹配大小写过滤

2、匹配全角半角过滤

3、匹配过滤停顿词过滤。

4、敏感词重复词过滤。

例如:

支持如下类型类型过滤检测:
fuck 全小写
FuCk 大小写
fuck全角半角
f!!!u&c ###k 停顿词
fffuuuucccckkk 重复词

二、代码实现

其目录结构如下:

其中resources资源目录中:

stopwd.txt :停顿词,匹配时间直接过滤。

wd.txt:敏感词库。

1、WordFilter敏感词过滤类

package org.andy.sensitivewdfilter;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;import org.andy.sensitivewdfilter.util.BCConvert;/*** 创建时间:2016年8月30日 下午3:01:12* * 思路: 创建一个FilterSet,枚举了0~65535的所有char是否是某个敏感词开头的状态* * 判断是否是 敏感词开头 | | 是 不是 获取头节点 OK--下一个字 然后逐级遍历,DFA算法* * @author andy* @version 2.2*/
public class WordFilter {private static final FilterSet set = new FilterSet(); // 存储首字private static final Map<Integer, WordNode> nodes = new HashMap<Integer, WordNode>(1024, 1); // 存储节点private static final Set<Integer> stopwdSet = new HashSet<>(); // 停顿词private static final char SIGN = '*'; // 敏感词过滤替换static {try {long a = System.nanoTime();init();a = System.nanoTime() - a;System.out.println("加载时间 : " + a + "ns");System.out.println("加载时间 : " + a / 1000000 + "ms");} catch (Exception e) {throw new RuntimeException("初始化过滤器失败");}}private static void init() {// 获取敏感词addSensitiveWord(readWordFromFile("wd.txt"));addStopWord(readWordFromFile("stopwd.txt"));}/*** 增加敏感词* @param path* @return*/private static List<String> readWordFromFile(String path) {List<String> words;BufferedReader br = null;try {br = new BufferedReader(new InputStreamReader(WordFilter.class.getClassLoader().getResourceAsStream(path)));words = new ArrayList<String>(1200);for (String buf = ""; (buf = br.readLine()) != null;) {if (buf == null || buf.trim().equals(""))continue;words.add(buf);}} catch (Exception e) {throw new RuntimeException(e);} finally {try {if (br != null)br.close();} catch (IOException e) {}}return words;}/*** 增加停顿词* * @param words*/private static void addStopWord(final List<String> words) {if (words != null && words.size() > 0) {char[] chs;for (String curr : words) {chs = curr.toCharArray();for (char c : chs) {stopwdSet.add(charConvert(c));}}}}/*** 添加DFA节点* @param words*/private static void addSensitiveWord(final List<String> words) {if (words != null && words.size() > 0) {char[] chs;int fchar;int lastIndex;WordNode fnode; // 首字母节点for (String curr : words) {chs = curr.toCharArray();fchar = charConvert(chs[0]);if (!set.contains(fchar)) {// 没有首字定义set.add(fchar);// 首字标志位 可重复add,反正判断了,不重复了fnode = new WordNode(fchar, chs.length == 1);nodes.put(fchar, fnode);} else {fnode = nodes.get(fchar);if (!fnode.isLast() && chs.length == 1)fnode.setLast(true);}lastIndex = chs.length - 1;for (int i = 1; i < chs.length; i++) {fnode = fnode.addIfNoExist(charConvert(chs[i]), i == lastIndex);}}}}/*** 过滤判断 将敏感词转化为成屏蔽词* @param src* @return*/public static final String doFilter(final String src) {char[] chs = src.toCharArray();int length = chs.length;int currc;int k;WordNode node;for (int i = 0; i < length; i++) {currc = charConvert(chs[i]);if (!set.contains(currc)) {continue;}node = nodes.get(currc);// 日 2if (node == null)// 其实不会发生,习惯性写上了continue;boolean couldMark = false;int markNum = -1;if (node.isLast()) {// 单字匹配(日)couldMark = true;markNum = 0;}// 继续匹配(日你/日你妹),以长的优先// 你-3 妹-4 夫-5k = i;for (; ++k < length;) {int temp = charConvert(chs[k]);if (stopwdSet.contains(temp))continue;node = node.querySub(temp);if (node == null)// 没有了break;if (node.isLast()) {couldMark = true;markNum = k - i;// 3-2}}if (couldMark) {for (k = 0; k <= markNum; k++) {chs[k + i] = SIGN;}i = i + markNum;}}return new String(chs);}/*** 是否包含敏感词* @param src* @return*/public static final boolean isContains(final String src) {char[] chs = src.toCharArray();int length = chs.length;int currc;int k;WordNode node;for (int i = 0; i < length; i++) {currc = charConvert(chs[i]);if (!set.contains(currc)) {continue;}node = nodes.get(currc);// 日 2if (node == null)// 其实不会发生,习惯性写上了continue;boolean couldMark = false;if (node.isLast()) {// 单字匹配(日)couldMark = true;}// 继续匹配(日你/日你妹),以长的优先// 你-3 妹-4 夫-5k = i;for (; ++k < length;) {int temp = charConvert(chs[k]);if (stopwdSet.contains(temp))continue;node = node.querySub(temp);if (node == null)// 没有了break;if (node.isLast()) {couldMark = true;}}if (couldMark) {return true;}}return false;}/*** 大写转化为小写 全角转化为半角* * @param src* @return*/private static int charConvert(char src) {int r = BCConvert.qj2bj(src);return (r >= 'A' && r <= 'Z') ? r + 32 : r;}}

其中:

isContains :是否包含敏感词

doFilter:过滤敏感词

2、WordNode敏感词节点

package org.andy.sensitivewdfilter;import java.util.LinkedList;
import java.util.List;/*** 创建时间:2016年8月30日 下午3:07:45* * @author andy* @version 2.2*/
public class WordNode {private int value; // 节点名称private List<WordNode> subNodes; // 子节点private boolean isLast;// 默认falsepublic WordNode(int value) {this.value = value;}public WordNode(int value, boolean isLast) {this.value = value;this.isLast = isLast;}/*** * @param subNode* @return 就是传入的subNode*/private WordNode addSubNode(final WordNode subNode) {if (subNodes == null)subNodes = new LinkedList<WordNode>();subNodes.add(subNode);return subNode;}/*** 有就直接返回该子节点, 没有就创建添加并返回该子节点* * @param value* @return*/public WordNode addIfNoExist(final int value, final boolean isLast) {if (subNodes == null) {return addSubNode(new WordNode(value, isLast));}for (WordNode subNode : subNodes) {if (subNode.value == value) {if (!subNode.isLast && isLast)subNode.isLast = true;return subNode;}}return addSubNode(new WordNode(value, isLast));}public WordNode querySub(final int value) {if (subNodes == null) {return null;}for (WordNode subNode : subNodes) {if (subNode.value == value)return subNode;}return null;}public boolean isLast() {return isLast;}public void setLast(boolean isLast) {this.isLast = isLast;}@Overridepublic int hashCode() {return value;}}

三、测试结果

项目包含敏感词库,源码,停顿词库等,只需运行maven打jar包直接可运行。

博客来源:http://blog.csdn.net/fengshizty?viewmode=list

项目源码http://download.csdn.net/detail/fengshizty/9617695

Java实现DFA算法对敏感词、广告词过滤功能相关推荐

  1. java使用DFA算法实现敏感词过滤

    Java使用DFA算法实现敏感词过滤 DFA,全称 Deterministic Finite Automaton 即确定有穷自动机. 其特征为:有一个有限状态集合和一些从一个状态通向另一个状态的边,每 ...

  2. spring boot 使用DFA算法实现敏感词过滤

    spring boot 使用DFA算法实现敏感词过滤 敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的. DFA算法简介 DFA全称为:Deterministi ...

  3. 一种基于DFA算法的敏感词检测JAVA程序片段

    本文章提供一种基于DFA算法的敏感词检测JAVA程序片段,如下: 1.构造多叉树数据结构 import org.jetbrains.annotations.NotNull;/*** 多叉树* @aut ...

  4. 基于PHP的DFA算法(敏感词过滤)

    基于PHP的DFA算法(敏感词过滤) 看到网上很多的DFA算法,很多都有不同程度的问题,自己修改了一下,亲测没有问题,用在系统中过滤敏感词汇,比正则匹配的速度快很多. class DFA {priva ...

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

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

  6. DFA算法实现敏感词过滤

    写项目时,得到一个新的需求,即实现敏感词的过滤,上网查了下,有几种实现方法,采取了DFA算法,即确定的有穷自动机算法,当初学习编译原理的时候为啥没想到DFA还能这么做,看来眼界和意识还是不够,得锻炼. ...

  7. dfa算法 java_Java实现DFA算法对敏感词、广告词过滤功能示例

    一.前言 开发中经常要处理用户一些文字的提交,所以涉及到了敏感词过滤的功能,参考资料中DFA有穷状态机算法的实现,创建有向图.完成了对敏感词.广告词的过滤,而且效率较好,所以分享一下. 具体实现: 1 ...

  8. DFA算法进行敏感词过滤

    1.新建敏感词文本new_adress.txt,进行添加敏感词 2.代码 # -*- coding:utf-8 -*- import timetime1 = time.time() "&qu ...

  9. 下发策略,DFA算法优化---敏感词查询

    1.定义 有穷自动机FA(Finite Automaton)的每一步操作都是确定的,因此可称为确定型有穷自动机.确定有穷自动机DFA(Deterministic Finite Automaton)就是 ...

  10. 手机视频直播系统开发关于Js敏感词替换成*功能介绍

    手机视频直播系统开发关于Js敏感词替换成*功能介绍,实现字符串过滤的方式有很多种,每个编程语言都有相应的处理方式,因语言不同,所使用的函数就有所不同,但最终的目的都是为达到用户的绿色上网,及安全上网, ...

最新文章

  1. OWASP top 10 (2017) 学习笔记--失效的身份验证
  2. mysql providername_c#访问各数据库的providerName各驱动-阿里云开发者社区
  3. python面试常见问题-10个Python面试常问的问题
  4. 【❗JS奇技淫巧❗】JavaScript:截取DataURL中的base64字符串
  5. 阿里妈妈技术团队 5 篇论文入选 TheWebConf 2022
  6. indexOf与includes的区别
  7. 图像处理常见算法(C++/OpenCV)
  8. Redis基础6(Redis6管道)
  9. vue学习(9)-路由守卫
  10. jedis默认切片实现及对应python版本实现
  11. PowerBuilder 9日历控件展示,下载(附带源码)2
  12. 三维重建开源项目汇总
  13. [玩转BLE]瑞昱RTL8762CMF蓝牙5.0(烧录篇)
  14. MATLAB(四) 图像处理--对象分析与属性
  15. 如何完美的卸载Office2007?
  16. 造DPU芯片,如梦幻泡影?丨虚构短篇小说
  17. springBoot接入阿里云oss
  18. Linux 脚本修改ps1,Linux使环境变量PS1的修改永久生效——修改配置文件/etc/profile...
  19. 浏览器 .avi视频播放demo
  20. 律师学python有什么用呢_《律》字意思读音、组词解释及笔画数 - 新华字典 - 911查询...

热门文章

  1. python中字符a如何变成b_python 如何把'a=b'这样的字符解析成dict类型
  2. mysql union all 等效_Mysql联合查询UNION和UNION ALL的使用介绍
  3. 用html设计倒计时秒表,Javascript实现秒表倒计时功能
  4. 汇编程序实现快速排序_用Python 3实现快速排序和插入排序代码详解
  5. RNA_seq(1)植物转录组实战(下)之DESeq2进行差异基因分析
  6. 力扣题目算法分类【持续更新】
  7. VB 显示当前时间 24小时制
  8. css background 旋转_纯CSS画小电视
  9. 360修复高危漏洞可以修复吗_大理石刮痕可以修复吗?如何修复?
  10. Ten graph questions of about 2000 difficulty of Codeforces Round 1