java利用DFA算法实现敏感词过滤功能

在最近的开发中遇到了敏感词过滤,便去网上查阅了很多敏感词过滤的资料,在这里也和大家分享一下自己的理解。下面这篇文章主要给大家介绍了关于java利用DFA算法实现敏感词过滤功能的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。

前言

敏感词过滤应该是不用给大家过多的解释吧?讲白了就是你在项目中输入某些字(比如输入xxoo相关的文字时)时要能检

测出来,很多项目中都会有一个敏感词管理模块,在敏感词管理模块中你可以加入敏感词,然后根据加入的敏感词去过滤输

入内容中的敏感词并进行相应的处理,要么提示,要么高亮显示,要么直接替换成其它的文字或者符号代替。

敏感词过滤的做法有很多,我简单描述我现在理解的几种:

①查询数据库当中的敏感词,循环每一个敏感词,然后去输入的文本中从头到尾搜索一遍,看是否存在此敏感词,有则做相

应的处理,这种方式讲白了就是找到一个处理一个。

优点:so easy。用java代码实现基本没什么难度。

缺点:这效率让我心中奔过十万匹草泥马,而且匹配的是不是有些蛋疼,如果是英文时你会发现一个很无语的事情,比如英文

a是敏感词,那我如果是一篇英文文档,那程序它妹的得处理多少次敏感词?谁能告诉我?

②传说中的DFA算法(有穷自动机),也正是我要给大家分享的,毕竟感觉比较通用,算法的原理希望大家能够自己去网上查查

资料,这里就不详细说明了。

优点:至少比上面那sb效率高点。

缺点:对于学过算法的应该不难,对于没学过算法的用起来也不难,就是理解起来有点gg疼,匹配效率也不高,比较耗费内存,

敏感词越多,内存占用的就越大。

③第三种在这里要特别说明一下,那就是你自己去写一个算法吧,或者在现有的算法的基础上去优化,这也是追求的至高境界之一。

那么,传说中的DFA算法是怎么实现的呢?

第一步:敏感词库初始化(将敏感词用DFA算法的原理封装到敏感词库中,敏感词库采用HashMap保存),代码如下:

 package com.cfwx.rox.web.sysmgr.util; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import com.cfwx.rox.web.common.model.entity.SensitiveWord; /** * 敏感词库初始化 * * @author AlanLee * */ public class SensitiveWordInit { /** * 敏感词库 */ public HashMap sensitiveWordMap; /** * 初始化敏感词 * * @return */ public Map initKeyWord(List sensitiveWords) { try { // 从敏感词集合对象中取出敏感词并封装到Set集合中 Set keyWordSet = new HashSet(); for (SensitiveWord s : sensitiveWords) { keyWordSet.add(s.getContent().trim()); } // 将敏感词库加入到HashMap中 addSensitiveWordToHashMap(keyWordSet); } catch (Exception e) { e.printStackTrace(); } return sensitiveWordMap; } /** * 封装敏感词库 * * @param keyWordSet */ @SuppressWarnings("rawtypes") private void addSensitiveWordToHashMap(Set keyWordSet) { // 初始化HashMap对象并控制容器的大小 sensitiveWordMap = new HashMap(keyWordSet.size()); // 敏感词 String key = null; // 用来按照相应的格式保存敏感词库数据 Map nowMap = null; // 用来辅助构建敏感词库 Map newWorMap = null; // 使用一个迭代器来循环敏感词集合 Iterator iterator = keyWordSet.iterator(); while (iterator.hasNext()) { key = iterator.next(); // 等于敏感词库,HashMap对象在内存中占用的是同一个地址,所以此nowMap对象的变化,sensitiveWordMap对象也会跟着改变 nowMap = sensitiveWordMap; for (int i = 0; i (); newWorMap.put("isEnd", "0"); nowMap.put(keyChar, newWorMap); nowMap = newWorMap; } // 如果该字是当前敏感词的最后一个字,则标识为结尾字 if (i == key.length() - 1) { nowMap.put("isEnd", "1"); } System.out.println("封装敏感词库过程:"+sensitiveWordMap); } System.out.println("查看敏感词库数据:" + sensitiveWordMap); } } }

第二步:写一个敏感词过滤工具类,里面可以写上自己需要的方法,代码如下:

 package com.cfwx.rox.web.sysmgr.util; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; /** * 敏感词过滤工具类 * * @author AlanLee * */ public class SensitivewordEngine { /** * 敏感词库 */ public static Map sensitiveWordMap = null; /** * 只过滤最小敏感词 */ public static int minMatchTYpe = 1; /** * 过滤所有敏感词 */ public static int maxMatchType = 2; /** * 敏感词库敏感词数量 * * @return */ public static int getWordSize() { if (SensitivewordEngine.sensitiveWordMap == null) { return 0; } return SensitivewordEngine.sensitiveWordMap.size(); } /** * 是否包含敏感词 * * @param txt * @param matchType * @return */ public static boolean isContaintSensitiveWord(String txt, int matchType) { boolean flag = false; for (int i = 0; i  0) { flag = true; } } return flag; } /** * 获取敏感词内容 * * @param txt * @param matchType * @return 敏感词内容 */ public static Set getSensitiveWord(String txt, int matchType) { Set sensitiveWordList = new HashSet(); for (int i = 0; i  0) { // 将检测出的敏感词保存到集合中 sensitiveWordList.add(txt.substring(i, i + length)); i = i + length - 1; } } return sensitiveWordList; } /** * 替换敏感词 * * @param txt * @param matchType * @param replaceChar * @return */ public static String replaceSensitiveWord(String txt, int matchType, String replaceChar) { String resultTxt = txt; Set set = getSensitiveWord(txt, matchType); Iterator 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 */ private static String getReplaceChars(String replaceChar, int length) { String resultReplace = replaceChar; for (int i = 1; i 

第三步:一切都准备就绪,当然是查询好数据库当中的敏感词,并且开始过滤咯,代码如下:

 @SuppressWarnings("rawtypes") @Override public Set sensitiveWordFiltering(String text) { // 初始化敏感词库对象 SensitiveWordInit sensitiveWordInit = new SensitiveWordInit(); // 从数据库中获取敏感词对象集合(调用的方法来自Dao层,此方法是service层的实现类) List sensitiveWords = sensitiveWordDao.getSensitiveWordListAll(); // 构建敏感词库 Map sensitiveWordMap = sensitiveWordInit.initKeyWord(sensitiveWords); // 传入SensitivewordEngine类中的敏感词库 SensitivewordEngine.sensitiveWordMap = sensitiveWordMap; // 得到敏感词有哪些,传入2表示获取所有敏感词 Set set = SensitivewordEngine.getSensitiveWord(text, 2); return set; }

最后一步:在Controller层写一个方法给前端请求,前端获取到需要的数据并进行相应的处理,代码如下:

 /** * 敏感词过滤 * * @param text * @return */ @RequestMapping(value = "/word/filter") @ResponseBody public RespVo sensitiveWordFiltering(String text) { RespVo respVo = new RespVo(); try { Set set = sensitiveWordService.sensitiveWordFiltering(text); respVo.setResult(set); } catch (Exception e) { throw new RoxException("过滤敏感词出错,请联系维护人员"); } return respVo; }

总结

以上就是这篇文章的全部内容了,代码中写了不少的注释,大家可以动动自己的脑筋好好的理解一下。希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对html中文网的支持。

以上就是java利用DFA算法实现敏感词过滤功能的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » Java