代码语言
.
CSharp
.
JS
Java
Asp.Net
C
MSSQL
PHP
Css
PLSQL
Python
Shell
EBS
ASP
Perl
ObjC
VB.Net
VBS
MYSQL
GO
Delphi
AS
DB2
Domino
Rails
ActionScript
Scala
代码分类
文件
系统
字符串
数据库
网络相关
图形/GUI
多媒体
算法
游戏
Jquery
Extjs
Android
HTML5
菜单
网页交互
WinForm
控件
企业应用
安全与加密
脚本/批处理
开放平台
其它
【
Java
】
DFA算法实现敏感词过滤工具类
作者:
/ 发布于
2019/7/10
/
705
此工具类通过hashmap构建敏感词树,利用DFA算法进行处理,共提供五个工具方法,方法如下: ?* void???SensiWordUtil.refreshSensiMap() ?刷新、重新生成敏感词汇树 ?* void ? SensiWordUtil.isContaintSensitiveWord(String txt) ?判断txt中是否存在敏感词 ?* String ? SensiWordUtil.replaceSensitiveWord(String txt,String replaceChar) ?用replaceChar替换txt中的敏感词,并返回结果 ?* boolean SensiWordUtil.delWord(String word) ?删除一个敏感词汇 ?* boolean SensiWordUtil.addWord(String word) ?添加一个敏感词汇 package myf.sensitive; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; /** * 敏感词过滤工具类 * * @author muyunfei * @QQ 1147417467 * @tel 15562579597 * * Modification History: * Date Author Description * ------------------------------------------------------------------ * Dec 22, 2016 牟云飞 新建 * * 返回结果 调用方式 * void SensiWordUtil.refreshSensiMap() 刷新、重新生成敏感词汇树 * void SensiWordUtil.isContaintSensitiveWord(String txt) 判断txt中是否存在敏感词 * String SensiWordUtil.replaceSensitiveWord(String txt,String replaceChar) 用replaceChar替换txt中的敏感词,并返回结果 * boolean SensiWordUtil.delWord(String word) 删除一个敏感词汇 * boolean SensiWordUtil.addWord(String word) 添加一个敏感词汇 */ public class SensiWordUtil { public static void main(String[] args) { //转载表明出处 牟云飞 http://blog.csdn.net/myfmyfmyfmyf/article/details/53835513 //测试时在D盘创建敏感词库 D:\\SensitiveWord.txt SensiWordUtil util = new SensiWordUtil(); String inputContext = "计算机(computer)俗称电脑,是现代一种用于高速计算的电子计算机器,三级片通常指含有色情" + "暴露镜头的电影,源自香港在八十年代末起进行的电影分级制。自1988年底香港实行电影分级制度以来,对第三级影片的" + "划分标准除了裸露镜头外又可以进行逻辑计算,还具有自杀功能。是能够按照法轮功程序运行,自动、高速处理海量黄色电影"; System.out.println("待检测语句字数:" + inputContext.length()); long beginTime = System.currentTimeMillis(); String newStr = SensiWordUtil.replaceSensitiveWord(inputContext,"*"); long endTime = System.currentTimeMillis(); System.out.println("过滤敏感词后:" + newStr); System.out.println("总共消耗时间为:" + (endTime - beginTime)); } //词库树 private static HashMap sensitiveWordMap = null; /** * 初始化敏感词树 * @return */ private static void initKeyWord(){ try { //读取敏感词库 List<String> keyWordList = readSensitiveWordFile(); //将敏感词库加入到HashMap中 addSensitiveWordToHashMap(keyWordList); } catch (Exception e) { e.printStackTrace(); } } /** * 删除一个敏感词词汇,true 删除成功 * @param word * @return */ public static boolean delWord(String word){ boolean flag = false; if(null==sensitiveWordMap||sensitiveWordMap.isEmpty()){ //没有敏感词树,直接返回false return false; } if(null==word||"".endsWith(word)){ //输入的词汇有误,返回false return false; } Map curNote = sensitiveWordMap; for (int i = 0; i < word.length(); i++) { char wordChar = word.charAt(i); //获取 Object wordMap = curNote.get(wordChar); if(null==wordMap){ //不存在当前敏感词汇 return true; } //判断是否最后一个词 Map temp = (Map) wordMap; String isEndVal = temp.get("isEnd")+""; if("1".equals(isEndVal)&&i==word.length()-1){ //找到了最后一个节点,删除 curNote.remove(wordChar); return true; } if("1".equals(isEndVal)&&i!=word.length()-1){ //不存在当前词汇 return true; } //递归当前点 curNote=(Map) wordMap; } return flag; } /** * 添加一个新词到树 * @param word * @return */ public static boolean addWord(String word){ try{ if(null==sensitiveWordMap){ //初始化敏感词容器 sensitiveWordMap = new HashMap(); } Map curMap = sensitiveWordMap; Map newWorMap =null; for(int i = 0 ; i < word.length() ; i++){ char keyChar = word.charAt(i); //转换成char型 Object wordMap = curMap.get(keyChar); //获取 if(wordMap != null){ //如果存在该key,直接赋值 curMap = (Map) wordMap; } else{ //不存在则,则构建一个map,同时将isEnd设置为0,因为他不是最后一个 newWorMap = new HashMap<String,String>(); newWorMap.put("isEnd", "0"); //不是最后一个 curMap.put(keyChar, newWorMap); curMap = newWorMap; } if(i == word.length() - 1){ curMap.put("isEnd", "1"); //最后一个 } } return true; }catch (Exception e) { e.printStackTrace(); return false; } } private static int minMatchTYpe = 1; //最小匹配规则 private static int maxMatchType = 2; //最大匹配规则 /** * 读取敏感词库中的内容 * @return * @throws Exception */ private static List<String> readSensitiveWordFile() throws Exception{ List<String> list = null; File file = new File("D:\\SensitiveWord.txt"); //读取文件 InputStreamReader read = new InputStreamReader(new FileInputStream(file),"GBK"); try { if(file.isFile() && file.exists()){ //文件流是否存在 list = new ArrayList<String>(); BufferedReader bufferedReader = new BufferedReader(read); String txt = null; while((txt = bufferedReader.readLine()) != null){ //读取文件,将文件内容放入到set中 list.add(txt); } } else{ //不存在抛出异常信息 throw new Exception("敏感词库文件不存在"); } } catch (Exception e) { throw e; }finally{ read.close(); //关闭文件流 } return list; } /** * 读取敏感词库,将敏感词放入HashSet中,构建一个DFA算法模型: * 中 = { * isEnd = 0 * 国 = { * isEnd = 1 * 人 = {isEnd = 0 * 民 = {isEnd = 1} * } * 男 = { * isEnd = 0 * 人 = { * isEnd = 1 * } * } * } * } * 五 = { * isEnd = 0 * 星 = { * isEnd = 0 * 红 = { * isEnd = 0 * 旗 = { * isEnd = 1 * } * } * } * } * * @param keyWordSet */ private static void addSensitiveWordToHashMap(List<String> keyWordList) { if(null==keyWordList||0==keyWordList.size()){ return; } sensitiveWordMap = new HashMap(keyWordList.size()); //初始化敏感词容器,减少扩容操作 String key = null; Map nowMap = null; Map<String, String> newWorMap = null; //迭代keyWordSet for (int j = 0; j < keyWordList.size(); j++) { key = keyWordList.get(j); //关键字 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"); //最后一个 } } } } /** * 判断文字是否包含敏感字符 * @param txt 检测字 * @return */ public static boolean isContaintSensitiveWord(String txt){ int matchType=1; //匹配规则?1:最小匹配规则,2:最大匹配规则 if(null==sensitiveWordMap||sensitiveWordMap.isEmpty()){ //如果敏感词树不存在创建 initKeyWord(); //如果初始化之后还是null,则没有敏感词库 if(null==sensitiveWordMap){ return false; } } boolean flag = false; for(int i = 0 ; i < txt.length() ; i++){ int matchFlag = CheckSensitiveWord(txt, i, matchType); //判断是否包含敏感字符 if(matchFlag > 0){ //大于0存在,返回true flag = true;break; } } return flag; } /** * 检查文字中是否包含敏感字符,如果存在,则返回敏感词字符的长度,不存在返回0 * @param txt * @param beginIndex * @param matchType * @return */ private static int CheckSensitiveWord(String txt,int beginIndex,int matchType){ boolean flag = false; //敏感词结束标识位:用于敏感词只有1位的情况 int matchFlag = 0; //匹配标识数默认为0 char word = 0; Map nowMap = sensitiveWordMap; for(int i = beginIndex; i < txt.length() ; i++){ word = txt.charAt(i); nowMap = (Map) nowMap.get(word); //获取指定key if(nowMap != null){ //存在,则判断是否为最后一个 matchFlag++; //找到相应key,匹配标识+1 if("1".equals(nowMap.get("isEnd"))){ //如果为最后一个匹配规则,结束循环,返回匹配标识数 flag = true; //结束标志位为true if(minMatchTYpe == matchType){ //最小规则,直接返回,最大规则还需继续查找 break; } } } else{ //不存在,直接返回 break; } } if(!flag){ matchFlag = 0; } return matchFlag; } /** * 替换敏感字字符 * @param txt * @param replaceChar * @return */ public static String replaceSensitiveWord(String txt,String replaceChar){ if(null==sensitiveWordMap||sensitiveWordMap.isEmpty()){ //如果敏感词树不存在创建 initKeyWord(); //如果初始化之后还是null,则没有敏感词库 if(null==sensitiveWordMap){ return txt; } } int matchType= 1; 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 txt * @param matchType * @return */ private static Set<String> getSensitiveWord(String txt , int matchType){ Set<String> sensitiveWordList = new HashSet<String>(); 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 replaceChar * @param length * @return */ private static String getReplaceChars(String replaceChar,int length){ String resultReplace = replaceChar; for(int i = 1 ; i < length ; i++){ resultReplace += replaceChar; } return resultReplace; } /** * 刷新敏感树 * @return */ public static boolean refreshSensiMap(){ try{ //清空原有的敏感词汇树 sensitiveWordMap=null; //初始化 initKeyWord(); return true; }catch (Exception e) { e.printStackTrace(); return false; } } }
试试其它关键字
DFA算法实现敏感词过滤工具类
同语言下
.
List 切割成几份 工具类
.
一行一行读取txt的内容
.
Java PDF转换成图片并输出给前台展示
.
java 多线程框架
.
double类型如果小数点后为零则显示整数否则保留两位小
.
将图片转换为Base64字符串公共类抽取
.
sqlParser 处理SQL(增删改查) 替换schema 用于多租户
.
JAVA 月份中的第几周处理 1-7属于第一周 依次类推 29-
.
java计算两个经纬度之间的距离
.
输入时间参数计算年龄
可能有用的
.
C#实现的html内容截取
.
List 切割成几份 工具类
.
SQL查询 多列合并成一行用逗号隔开
.
一行一行读取txt的内容
.
C#动态修改文件夹名称(FSO实现,不移动文件)
.
c# 移动文件或文件夹
.
c#图片添加水印
.
Java PDF转换成图片并输出给前台展示
.
网站后台修改图片尺寸代码
.
处理大图片在缩略图时的展示
贡献的其它代码
Label
Copyright © 2004 - 2024 dezai.cn. All Rights Reserved
站长博客
粤ICP备13059550号-3