DFA算法实现敏感词过滤
DFA算法:即确定有穷自动机,简单点说就是,它是是通过event和当前的state得到下一个state,即event+state=nextstate。理解为系统中有多个节点,通过传递进入的event,来确定走哪个路由至另一个节点,而节点是有限的。
废话不多说,直接贴上代码:
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 java.util.regex.Matcher;
import java.util.regex.Pattern; /**
* @description:敏感词工具
* @author: maojialong
* @date: 2018年1月30日 上午10:59:24
*/
public class SensitivewordEngine { private String ENCODING = "GBK"; //字符编码 //敏感词库
public static Map sensitiveWordMap = new HashMap(); //只过滤最小敏感词
public static int minMatchTYpe = 1; //过滤所有敏感词
public static int maxMatchType = 2; //正则表达式中文、字母、数字
public static Pattern pattern = Pattern.compile("^[a-zA-Z0-9\u4E00-\u9FA5]+$"); /**
* 读取敏感词库中的内容,将内容添加到set集合中
* @author chenming
* @date 2014年4月20日 下午2:31:18
* @return
* @version 1.0
* @throws Exception
*/
@SuppressWarnings("resource")
private void readSensitiveWordFile() throws Exception{
Set<String> set = null; File file = new File("D:\\SensitiveWord.txt"); //读取文件
InputStreamReader read = new InputStreamReader(new FileInputStream(file),ENCODING);
try {
if(file.isFile() && file.exists()){ //文件流是否存在
set = new HashSet<String>();
BufferedReader bufferedReader = new BufferedReader(read);
String txt = null;
while((txt = bufferedReader.readLine()) != null){ //读取文件,将文件内容放入到set中
set.add(txt);
}
}
else{ //不存在抛出异常信息
throw new Exception("敏感词库文件不存在");
}
} catch (Exception e) {
throw e;
}finally{
read.close(); //关闭文件流
}
addNewSensitiveWord(set);
} /**
* @description: 新增敏感词库
* @author: maojialong
* @date: 2018年2月1日 上午11:55:10
* @param keyWordSet
*/
public static void addNewSensitiveWord(Set<String> keyWordSet) {
sensitiveWordMap.putAll(getNewSensitiveWordToHashMap(keyWordSet));
} /**
* @description: 封装敏感词库
* @author: maojialong
* @date: 2018年1月30日 下午4:28:58
* @param keyWordSet
* @return
*/
@SuppressWarnings("rawtypes")
public static HashMap getNewSensitiveWordToHashMap(Set<String> keyWordSet) {
// 初始化HashMap对象并控制容器的大小
HashMap newSensitiveWordMap = new HashMap(keyWordSet.size());
// 敏感词
String key = null;
// 用来按照相应的格式保存敏感词库数据
Map nowMap = null;
// 用来辅助构建敏感词库
Map<String, String> newWorMap = null;
// 使用一个迭代器来循环敏感词集合
Iterator<String> iterator = keyWordSet.iterator();
while (iterator.hasNext()) {
key = iterator.next();
// 等于敏感词库,HashMap对象在内存中占用的是同一个地址,所以此nowMap对象的变化,sensitiveWordMap对象也会跟着改变
nowMap = sensitiveWordMap;
for (int i = 0; i < key.length(); i++) {
// 截取敏感词当中的字,在敏感词库中字为HashMap对象的Key键值
char keyChar = key.charAt(i);
//不是汉字数字字母直接跳过
Matcher match = pattern.matcher(String.valueOf(keyChar));
boolean matched = match.matches();
if(!matched) {
continue;
} // 判断这个字是否存在于敏感词库中
Object wordMap = nowMap.get(keyChar);
if (wordMap != null) {
nowMap = (Map) wordMap;
} else {
newWorMap = new HashMap<String, String>();
newWorMap.put("isEnd", "0");
nowMap.put(keyChar, newWorMap);
nowMap = newWorMap;
} // 如果该字是当前敏感词的最后一个字,则标识为结尾字
if (i == key.length() - 1) {
nowMap.put("isEnd", "1");
}
}
}
return newSensitiveWordMap;
} /**
* @description: 敏感词库敏感词数量
* @author: maojialong
* @date: 2018年1月30日 下午4:07:20
* @return
*/
public static int getWordSize() {
if (SensitivewordEngine.sensitiveWordMap == null) {
return 0;
}
return SensitivewordEngine.sensitiveWordMap.size();
} /**
* @description: 是否包含敏感词
* @author: maojialong
* @date: 2018年1月30日 下午2:47:37
* @param txt
* @param matchType
* @return
*/
public static boolean isContaintSensitiveWord(String txt, int matchType) {
boolean flag = false;
for (int i = 0; i < txt.length(); i++) {
int matchFlag = checkSensitiveWord(txt, i, matchType);
if (matchFlag > 0) {
flag = true;
}
}
return flag;
} /**
* @description: 获取敏感词内容
* @author: maojialong
* @date: 2018年1月30日 下午2:47:27
* @param txt
* @param matchType
* @return
*/
public 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) {
// 将检测出的敏感词保存到集合中
sensitiveWordList.add(txt.substring(i, i + length));
i = i + length - 1;
}
} return sensitiveWordList;
} /**
* @description: 替换敏感词
* @author: maojialong
* @date: 2018年1月30日 下午2:47:15
* @param txt
* @param matchType
* @param replaceChar
* @return
*/
public static 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());
try {
resultTxt = resultTxt.replaceAll(word, replaceString);
}catch(Exception e) {
}
} return resultTxt;
} /**
* @description: 获取替换字符
* @author: maojialong
* @date: 2018年1月30日 下午2:46:40
* @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;
} /**
* @description: 检查敏感词
* @author: maojialong
* @date: 2018年1月30日 下午2:45:50
* @param txt
* @param beginIndex
* @param matchType
* @return
*/
public static int checkSensitiveWord(String txt, int beginIndex, int matchType) {
boolean flag = false;
// 记录敏感词数量
int matchFlag = 0;
char word = 0;
Map nowMap = SensitivewordEngine.sensitiveWordMap;
for (int i = beginIndex; i < txt.length(); i++) {
word = txt.charAt(i);
if(matchFlag > 0 && !flag ) {
Matcher match = pattern.matcher(String.valueOf(word));
boolean matched = match.matches();
if(!matched) {
matchFlag++;
continue;
}
}
// 判断该字是否存在于敏感词库中
nowMap = (Map) nowMap.get(word);
if (nowMap != null) {
matchFlag++;
// 判断是否是敏感词的结尾字,如果是结尾字则判断是否继续检测
if ("1".equals(nowMap.get("isEnd"))) {
flag = true;
// 判断过滤类型,如果是小过滤则跳出循环,否则继续循环
if (SensitivewordEngine.minMatchTYpe == matchType) {
break;
}
}
} else {
break;
}
}
if (matchFlag < 2 || !flag) {
matchFlag = 0;
}
return matchFlag;
} /**
* @description: 删除敏感词
* @author: maojialong
* @date: 2018年2月1日 上午11:40:45
* @param keyWord
*/
public static void removeSensitiveWordToHashMap(String keyWord) {
int length = keyWord.length();
Map<Integer,Map> tempMap = new HashMap<Integer,Map>();
char word = 0;
boolean flag = false;
Map nowMap = sensitiveWordMap;
for(int i = 0; i < length ; i++){
word = keyWord.charAt(i);
Map lastMap = nowMap;
nowMap = (Map) nowMap.get(word); //获取指定key
if(nowMap != null){ //存在,则判断是否为最后一个
tempMap.put(i, lastMap);
}else{ //不存在,直接返回
break;
}
if (i == length -1 && "1".equals(nowMap.get("isEnd"))) {
flag = true;
}
}
if(flag) {
for(int i = length - 1; i >= 0 ; i--){
word = keyWord.charAt(i);
nowMap = tempMap.get(i);
Map m = (Map) nowMap.get(word);
boolean last = m.size() == 1 && "1".equals(m.get("isEnd")) && i == length - 1;
boolean notLast = m.size() == 1 && "0".equals(m.get("isEnd"));
if(last || notLast) {
nowMap.remove(keyWord.charAt(i));
}else {
break;
}
}
}
} public static void main(String[] args) throws InterruptedException {
Set<String> sensitiveWord = new HashSet<String>();
sensitiveWord.add("大娃");
SensitivewordEngine.addNewSensitiveWord(sensitiveWord);
String result = SensitivewordEngine.replaceSensitiveWord("我是大娃,我弟弟是大二娃,我们都是葫芦娃", 2,"*");
System.out.println(result);
System.out.println(SensitivewordEngine.sensitiveWordMap); //新增或者批量新增
sensitiveWord.add("大二娃");
sensitiveWord.add("大二");
SensitivewordEngine.addNewSensitiveWord(sensitiveWord);
result = SensitivewordEngine.replaceSensitiveWord("我是大娃,我弟弟是大二娃,我们现在读大二,我们都是葫芦娃", 2,"*");
System.out.println(result);
System.out.println(SensitivewordEngine.sensitiveWordMap); //删除
SensitivewordEngine.removeSensitiveWordToHashMap("大二娃");
result = SensitivewordEngine.replaceSensitiveWord("我是大娃,我弟弟是大二娃,我们现在读大二,我们都是葫芦娃", 2,"*");
System.out.println(result);
System.out.println(SensitivewordEngine.sensitiveWordMap); } }
复制代码即可食用,最后的removeSensitiveWordToHashMap是我一个朋友帮忙写的,其他方法时参考网上的其他博文整理的
DFA算法实现敏感词过滤的更多相关文章
- 使用DFA算法对敏感词进行过滤
项目目录结构如下: 其中resources资源目录中: stopwd.txt :停顿词,匹配时间直接过滤. wd.txt:敏感词库. 1.WordFilter敏感词过滤类: package com.s ...
- Java 利用DFA算法 屏蔽敏感词
原文:http://www.open-open.com/code/view/1435214601278 import java.io.BufferedReader; import java.io.Fi ...
- Java实现敏感词过滤 - DFA算法
Java实现DFA算法进行敏感词过滤 封装工具类如下: 使用前需对敏感词库进行初始化: SensitiveWordUtil.init(sensitiveWordSet); package cn.swf ...
- 敏感词过滤的算法原理之DFA算法
参考文档 http://blog.csdn.net/chenssy/article/details/26961957 敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有 ...
- DFA和trie特里实现敏感词过滤(python和c语言)
今天的项目是与完成python开展,需要使用做关键词检查,筛选分类,使用前c语言做这种事情.有了线索,非常高效,内存小了,检查快. 到达python在,第一个想法是pip基于外观的c语言python特 ...
- Java实现敏感词过滤
敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的.前段时间我一个朋友(马上毕业,接触编程不久)要我帮他看一个文字过滤的东西,它说检索效率非常慢.我把它程序拿过来 ...
- Java实现敏感词过滤(转)
敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的.前段时间我一个朋友(马上毕业,接触编程不久)要我帮他看一个文字过滤的东西,它说检索效率非常慢.我把它程序拿过来 ...
- Jsp敏感词过滤
Jsp敏感词过滤 大部分论坛.网站等,为了方便管理,都进行了关于敏感词的设定. 在多数网站,敏感词一般是指带有敏感政治倾向(或反执政党倾向).暴力倾向.不健康色彩的词或不文明语,也有一些网站根据自身实 ...
- 转:Java实现敏感词过滤
敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的.前段时间我一个朋友(马上毕业,接触编程不久)要我帮他看一个文字过滤的东西,它说检索效率非常慢.我把它程序拿过来 ...
随机推荐
- 03_Spring Bean的装配模式_基于Annotation配置方式
前言 在Spring中尽管使用XML配置文件可以实现Bean的装配工作,但如果应用中Bean的数量较多,会导致XML配置文件过于臃肿,从而给维护和升级带来一定的困难.从JDK 5开始提供了名为Anno ...
- OSG实现正八面体剖分成球
#include<Windows.h> #include<osg/Node> #include<osg/Geode> #include<osg/Group&g ...
- /proc/cpuinfo和/proc/meminfo来查看cpu信息与内存信息
#一般情况下使用root或者oracle用户查都可以. # 总核数 = 物理CPU个数 X 每颗物理CPU的核数 # 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数 --查 ...
- List --搜索列表
1,常见的内建函数 . if val in L : # 是否在列表 . L.index(val) # 找下标 . L.count(val) # 有多少个 . min/max(L ) # 最大最小 . ...
- Python之MySQL语法(增删改查)
-- ID: 新闻的唯一标示 -- title: 新闻的标题 -- content: 新闻的内容 -- created_at: 新闻添加的时间 -- types: 新闻的类型 -- image: 新的 ...
- Python读写文件学习笔记
一. 基础 1.创建文件夹 import os os.makedirs('I:\\pythonWorkPace') # 创建文件夹 2. 获取文件夹里面文件列表 import os # os.make ...
- [转]Sql Server Alter语句
原文链接:http://www.cnblogs.com/yoolonet/archive/2010/12/10/1884782.html 在修改Sql Server表结构时,常用到Alter语句,把一 ...
- 移动端网站如何开发(电脑端网站到手机端网站我们需要在html代码中添加哪个meta标签)
移动端网站如何开发(电脑端网站到手机端网站我们需要在html代码中添加哪个meta标签) 一.总结 一句话总结: 添加viewport标签:meta name="viewport" ...
- Java下利用Jackson进行JSON解析和序列化1
Java下常见的Json类库有Gson.JSON-lib和Jackson等,Jackson相对来说比较高效,在项目中主要使用Jackson进行JSON和Java对象转换,下面给出一些Jackson的J ...
- numpy 常用工具函数 —— np.bincount/np.average
numpy 常用工具函数 —— np.bincount/np.average numpy 常用api(一) numpy 常用api(二) 一个函数提供 random_state 的关键字参数(keyw ...