遇到一个过滤敏感词的需求,根据网上查询的资料整理了一下,代码如下

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;import org.springframework.stereotype.Component;/*** 敏感词过滤bean** @author zhanchong* @email zhanchong316@foxmail.com* @date 2019-02-21 13:14:51*/
@Component
public class SensitivewordFilter {@SuppressWarnings("rawtypes")private Map sensitiveWordMap = null;private static int minMatchTYpe = 1; // 最小匹配规则// private static int maxMatchType = 2; // 最大匹配规则private String ENCODING = "UTF-8"; // 字符编码/*** 构造函数,初始化敏感词库*/private SensitivewordFilter() {this.sensitiveWordMap = initKeyWord();}/*** * @return*/@SuppressWarnings("rawtypes")private Map initKeyWord() {try {// 读取敏感词库Set<String> keyWordSet = readSensitiveWordFile();// 将敏感词库加入到HashMap中addSensitiveWordToHashMap(keyWordSet);// spring获取application,然后application.setAttribute("sensitiveWordMap",sensitiveWordMap);} catch (Exception e) {e.printStackTrace();}return sensitiveWordMap;}/*** 读取敏感词库,将敏感词放入HashSet中,构建一个DFA算法模型:<br>* 中 = { isEnd = 0 国 = {<br>* isEnd = 1 人 = {isEnd = 0 民 = {isEnd = 1} } 男 = { isEnd = 0 人 = { isEnd =* 1 } } } } 五 = { isEnd = 0 星 = { isEnd = 0 红 = { isEnd = 0 旗 = { isEnd = 1* } } } }* */@SuppressWarnings({ "rawtypes", "unchecked" })private void addSensitiveWordToHashMap(Set<String> keyWordSet) {sensitiveWordMap = new HashMap(keyWordSet.size()); // 初始化敏感词容器,减少扩容操作String key = null;Map nowMap = null;Map<String, String> newWorMap = null;// 迭代keyWordSetIterator<String> iterator = keyWordSet.iterator();while (iterator.hasNext()) {key = iterator.next(); // 关键字nowMap = sensitiveWordMap;for (int i = 0; i < key.length(); i++) {char keyChar = key.charAt(i); // 转换成char型Object wordMap = nowMap.get(keyChar); // 获取if (wordMap != null) { // 如果存在该key,直接赋值nowMap = (Map) wordMap;} else { // 不存在则,则构建一个map,同时将isEnd设置为0,因为他不是最后一个newWorMap = new HashMap<String, String>();newWorMap.put("isEnd", "0"); // 不是最后一个nowMap.put(keyChar, newWorMap);nowMap = newWorMap;}if (i == key.length() - 1) {nowMap.put("isEnd", "1"); // 最后一个}}}}/*** 读取敏感词库中的内容,将内容添加到set集合中* * @return* @throws Exception*/@SuppressWarnings("resource")private Set<String> readSensitiveWordFile() throws Exception {Set<String> set = null;String url = SensitivewordFilter.class.getResource("/key.txt").getFile();File file = new File(url); // 读取文件InputStreamReader read = new InputStreamReader(new FileInputStream(file), ENCODING);try {if (file.isFile() && file.exists()) { // 文件流是否存在set = new HashSet<>();BufferedReader bufferedReader = new BufferedReader(read);String txt;while ((txt = bufferedReader.readLine()) != null) { // 读取文件,将文件内容放入到set中set.add(txt);}} else { // 不存在抛出异常信息throw new Exception("敏感词库文件不存在");}} catch (Exception e) {throw e;} finally {read.close(); // 关闭文件流}return set;}/*** 判断文字是否包含敏感字符** @param txt*            文字* @param matchType*            匹配规则&nbsp;1:最小匹配规则,2:最大匹配规则* @return 若包含返回true,否则返回false*/public boolean isContaintSensitiveWord(String txt, int matchType) {boolean flag = false;for (int i = 0; i < txt.length(); i++) {int matchFlag = this.CheckSensitiveWord(txt, i, matchType); // 判断是否包含敏感字符if (matchFlag > 0) { // 大于0存在,返回trueflag = true;}}return flag;}/*** 获取文字中的敏感词** @param txt*            文字* @param matchType*            匹配规则&nbsp;1:最小匹配规则,2:最大匹配规则* @return*/public Set<String> getSensitiveWord(String txt, int matchType) {Set<String> sensitiveWordList = new HashSet<>();for (int i = 0; i < txt.length(); i++) {int length = CheckSensitiveWord(txt, i, matchType); // 判断是否包含敏感字符if (length > 0) { // 存在,加入list中sensitiveWordList.add(txt.substring(i, i + length));i = i + length - 1; // 减1的原因,是因为for会自增}}return sensitiveWordList;}/*** 替换敏感字字符** @param txt* @param matchType* @param replaceChar*            替换字符,默认**/public String replaceSensitiveWord(String txt, int matchType, String replaceChar) {String resultTxt = txt;Set<String> set = getSensitiveWord(txt, matchType); // 获取所有的敏感词Iterator<String> iterator = set.iterator();String word = null;String replaceString = null;while (iterator.hasNext()) {word = iterator.next();replaceString = getReplaceChars(replaceChar, word.length());resultTxt = resultTxt.replaceAll(word, replaceString);}return resultTxt;}/*** 获取替换字符串** @param replaceChar* @param length* @return*/public String getReplaceChars(String replaceChar, int length) {String resultReplace = replaceChar;for (int i = 1; i < length; i++) {resultReplace += replaceChar;}return resultReplace;}/*** 检查文字中是否包含敏感字符,检查规则如下:<br>** @param txt* @param beginIndex* @param matchType* @return,如果存在,则返回敏感词字符的长度,不存在返回0*/@SuppressWarnings({ "rawtypes" })public int CheckSensitiveWord(String txt, int beginIndex, int matchType) {boolean flag = false; // 敏感词结束标识位:用于敏感词只有1位的情况int matchFlag = 0; // 匹配标识数默认为0char word = 0;Map nowMap = sensitiveWordMap;for (int i = beginIndex; i < txt.length(); i++) {word = txt.charAt(i);nowMap = (Map) nowMap.get(word); // 获取指定keyif (nowMap != null) { // 存在,则判断是否为最后一个matchFlag++; // 找到相应key,匹配标识+1if ("1".equals(nowMap.get("isEnd"))) { // 如果为最后一个匹配规则,结束循环,返回匹配标识数flag = true; // 结束标志位为trueif (SensitivewordFilter.minMatchTYpe == matchType) { // 最小规则,直接返回,最大规则还需继续查找break;}}} else { // 不存在,直接返回break;}}if (matchFlag < 2 || !flag) { // 长度必须大于等于1,为词matchFlag = 0;}return matchFlag;}/*** 判断是否含有敏感词** @param word* @return*/public boolean isSensitive(String word) {Set<String> words = getSensitiveWord(word, 1);return words != null && words.size() > 0;}}

DFA算法实现的敏感词过滤器相关推荐

  1. 基于DFA算法实现文章敏感词过滤

    最近公司要出一个论坛系统 因为最近貌似xxx查的也比较严,所以图片和文字安全一样要注意 其中文字就涉及到敏感字过滤的问题 目前大概流传两种解决办法: 1.利用分词器分词实现过滤 比如见得比较多的 IK ...

  2. dfa算法 java_java实现敏感词过滤(DFA算法)

    小Alan在最近的开发中遇到了敏感词过滤,便去网上查阅了很多敏感词过滤的资料,在这里也和大家分享一下自己的理解. 在写之前,小Alan给大家推荐一篇来自http://cmsblogs.com/?p=1 ...

  3. 基于DFA算法实现过滤敏感词

    该篇文章主要是记录我在实现敏感词过滤的实现, 通常我们如果对于敏感词过滤的话,首先想到的肯定是,把敏感词库制成一个数组或List,然后循环查询该list或数组,然后判断该次循环的敏感词是否在传入的字符 ...

  4. DFA算法:简易Java敏感词过滤(含源文件和上万敏感词列表)

    敏感词过滤说白了就是简单的字符串替换,Java本身已经提供了相关函数,但是一旦遇到长文本,或者敏感词数量庞大,效率下降就会非常明显.本文将介绍利用多叉树进行敏感词存储和过滤的方法. 多叉树 多叉树是一 ...

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

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

  6. JAVA -敏感词过滤器 工具类SensitiveFilter

    1.添加敏感词过滤工具类 类1: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStre ...

  7. 敏感词过滤器 filter

    敏感词过滤器 filter /*** 敏感词过滤器*/ public class SensitiveWordsFilter implements Filter {// 敏感词列表private Str ...

  8. 用js模拟一个简单敏感词过滤器

    1.用js模拟一个简单敏感词过滤器 (用户输入的内容中的敏感词替换为*) 例:"今天有个傻子在旁边大喊大叫,影响了我的操作.", 过滤后:"今天有个在旁边大喊大叫,影响了 ...

  9. python敏感词过滤代码简单代码,Python学习笔记系列——读写文件以及敏感词过滤器的实现...

    一.读文件 #打开文件,传入文件名和标识符,r代表读 f= open('\\Users\ZC\Desktop\zc.txt','r') #调用read方法一次性读取文件的全部内容,存入内存,用str对 ...

最新文章

  1. java获取下一季末_java取当前周期、月初至月末、季度初至季度末日期。
  2. 有监督学习的算法fit(x,y)传两个参数无监督学习的算法是fit(x),即传一个参数
  3. java runnable 异常_JAVA 线程中的异常捕获
  4. ASP.NET 中 Cookie 的基本知识
  5. 拆卸invokedynamic
  6. 双向链表list.h升序排序
  7. python怎么更改背景颜色_python中绘图时怎么改背景颜色?
  8. 在线检查错别字校对软件 | 推荐
  9. 如何使用计算机中的导出,解决方案:如何使用Canon 2525i复印机将文档扫描到计算机中并生成PDF格式?...
  10. 希腊字母发音表及所对应的Markdown KaTex代码
  11. java swing界面设计_java swing界面设计
  12. 高中数学解析几何解题方法,2019高考生没有掌握方法!
  13. 双极性正弦脉宽调制(双极性SPWM)介绍及MATLAB仿真验证
  14. 「Android高级工程师」BAT大厂面试基础题集合-下 Github标星6.5K
  15. 原生js高仿浏览器ctrf+f
  16. springboot+Thymeleaf生成PDF
  17. 青云云服务器怎么上传文件,青云QingCloud发布文件存储,进一步完善软件定义存储解决方案...
  18. 别再付费了!霸屏朋友圈的“蚂蚁呀嘿”视频教程大公开
  19. Newman安装指南
  20. jvarkit包问题反馈:构建成功,部分方法测试失败第4类错误分析

热门文章

  1. 20230614-2
  2. 在Linux系统中安装eclipse
  3. win2012命令计算机,Windows2012重启的两种方法:cmd命令关机重启分享
  4. s2023gc65数三角形
  5. 在.NET中进行AutoCAD二次开发(C#+ObjectArx) (一)
  6. java-core-basic
  7. 学生硬件电路设计经验教训浅谈
  8. 高斯定理的理解——工程电磁场 P2~P5
  9. cas之soo单点登录初步探究
  10. 计算机动画制作试题,《Flash动画制作》模拟试题