原文:http://www.open-open.com/code/view/1435214601278

    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.Map;
import java.util.Set; /**
* 初始化敏感词库<br>
* 将敏感词加入到HashMap中<br>
* 构建DFA算法模型
*
* @author dxm
*
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class SensitiveWordInit { // 字符编码
private String ENCODING = "UTF-8"; /**
* 初始化敏感字库
*
* @return
*/
public Map initKeyWord() { // 读取敏感词库
Set<String> wordSet = readSensitiveWordFile(); // 将敏感词库加入到HashMap中
return addSensitiveWordToHashMap(wordSet);
} /**
* 读取敏感词库,将敏感词放入HashSet中,构建一个DFA算法模型:<br>
* 中 = { isEnd = 0 国 = {<br>
* isEnd = 1 人 = {isEnd = 0 民 = {isEnd = 1} } 男 = { isEnd = 0 人 = { isEnd =
* 1 } } } } 五 = { isEnd = 0 星 = { isEnd = 0 红 = { isEnd = 0 旗 = { isEnd = 1
* } } } }
*
*/
private Map addSensitiveWordToHashMap(Set<String> wordSet) { // 初始化敏感词容器,减少扩容操作
Map wordMap = new HashMap(wordSet.size()); for (String word : wordSet) {
Map nowMap = wordMap;
for (int i = 0; i < word.length(); i++) { // 转换成char型
char keyChar = word.charAt(i); // 获取
Object tempMap = nowMap.get(keyChar); // 如果存在该key,直接赋值
if (tempMap != null) {
nowMap = (Map) tempMap;
} // 不存在则,则构建一个map,同时将isEnd设置为0,因为他不是最后一个
else { // 设置标志位
Map<String, String> newMap = new HashMap<String, String>();
newMap.put("isEnd", "0"); // 添加到集合
nowMap.put(keyChar, newMap);
nowMap = newMap;
} // 最后一个
if (i == word.length() - 1) {
nowMap.put("isEnd", "1");
}
}
} return wordMap;
} /**
* 读取敏感词库中的内容,将内容添加到set集合中
*
* @return
* @throws Exception
*/
private Set<String> readSensitiveWordFile() { Set<String> wordSet = null; // 读取文件
String app = System.getProperty("user.dir");
File file = new File(app + "/src/sensitive.txt");
try { InputStreamReader read = new InputStreamReader(new FileInputStream(file), ENCODING); // 文件流是否存在
if (file.isFile() && file.exists()) { wordSet = new HashSet<String>();
StringBuffer sb = new StringBuffer();
BufferedReader bufferedReader = new BufferedReader(read);
String txt = null; // 读取文件,将文件内容放入到set中
while ((txt = bufferedReader.readLine()) != null) {
sb.append(txt);
}
bufferedReader.close(); String str = sb.toString();
String[] ss = str.split(",");
for (String s : ss) {
wordSet.add(s);
}
} // 关闭文件流
read.close(); } catch (Exception e) {
e.printStackTrace();
} return wordSet;
}
} import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set; /**
* 敏感词过滤
*
* @author dxm
*
*/
@SuppressWarnings("rawtypes")
public class SensitivewordFilter { private Map sensitiveWordMap = null; // 最小匹配规则
public static int minMatchTYpe = 1; // 最大匹配规则
public static int maxMatchType = 2; // 单例
private static SensitivewordFilter inst = null; /**
* 构造函数,初始化敏感词库
*/
private SensitivewordFilter() {
sensitiveWordMap = new SensitiveWordInit().initKeyWord();
} /**
* 获取单例
*
* @return
*/
public static SensitivewordFilter getInstance() {
if (null == inst) {
inst = new SensitivewordFilter();
}
return inst;
} /**
* 判断文字是否包含敏感字符
*
* @param txt
* @param matchType
* @return
*/
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); // 大于0存在,返回true
if (matchFlag > 0) {
flag = true;
}
}
return flag;
} /**
* 获取文字中的敏感词
*
* @param txt
* @param matchType
* @return
*/
public 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); // 存在,加入list中
if (length > 0) {
sensitiveWordList.add(txt.substring(i, i + length)); // 减1的原因,是因为for会自增
i = i + length - 1;
}
} return sensitiveWordList;
} /**
* 替换敏感字字符
*
* @param txt
* @param matchType
* @param replaceChar
* @return
*/
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
*/
private String getReplaceChars(String replaceChar, int length) {
String resultReplace = replaceChar;
for (int i = 1; i < length; i++) {
resultReplace += replaceChar;
} return resultReplace;
} /**
* 检查文字中是否包含敏感字符,检查规则如下:<br>
* 如果存在,则返回敏感词字符的长度,不存在返回0
*
* @param txt
* @param beginIndex
* @param matchType
* @return
*/
public int CheckSensitiveWord(String txt, int beginIndex, int matchType) { // 敏感词结束标识位:用于敏感词只有1位的情况
boolean flag = false; // 匹配标识数默认为0
int matchFlag = 0;
Map nowMap = sensitiveWordMap;
for (int i = beginIndex; i < txt.length(); i++) {
char word = txt.charAt(i); // 获取指定key
nowMap = (Map) nowMap.get(word); // 存在,则判断是否为最后一个
if (nowMap != null) { // 找到相应key,匹配标识+1
matchFlag++; // 如果为最后一个匹配规则,结束循环,返回匹配标识数
if ("1".equals(nowMap.get("isEnd"))) { // 结束标志位为true
flag = true; // 最小规则,直接返回,最大规则还需继续查找
if (SensitivewordFilter.minMatchTYpe == matchType) {
break;
}
}
} // 不存在,直接返回
else {
break;
}
} // 长度必须大于等于1,为词
if (matchFlag < 2 || !flag) {
matchFlag = 0;
}
return matchFlag;
} public static void main(String[] args) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS"); SensitivewordFilter filter = SensitivewordFilter.getInstance();
String txt = "太多的伤感情怀也许只局限于饲养基地 荧幕中的情节,主人公尝试着去用某种方式渐渐的很潇洒地释自杀指南怀那些自己经历的伤感。" + "然后法 轮功 我们的扮演的角色就是跟随着主人公的喜红客联盟 怒哀乐而过于牵强的把自己的情感也附加于银幕情节中,然后感动就流泪," + "难过就躺在某一个人的怀里尽情的阐述心扉或者手机卡复制器一个人一杯红酒一部电影在夜三级片 深人静的晚上,关上电话静静的发呆着。";
txt = "法 轮大法";
System.out.println(sdf.format(new Date()));
String hou = filter.replaceSensitiveWord(txt, 1, "*");
System.out.println(sdf.format(new Date()));
System.out.println("替换前的文字为:" + txt);
System.out.println("替换后的文字为:" + hou);
}
}

Java 利用DFA算法 屏蔽敏感词的更多相关文章

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

    DFA算法:即确定有穷自动机,简单点说就是,它是是通过event和当前的state得到下一个state,即event+state=nextstate.理解为系统中有多个节点,通过传递进入的event, ...

  2. 使用DFA算法对敏感词进行过滤

    项目目录结构如下: 其中resources资源目录中: stopwd.txt :停顿词,匹配时间直接过滤. wd.txt:敏感词库. 1.WordFilter敏感词过滤类: package com.s ...

  3. 利用 DFA 算法实现文字过滤

    一.DEA 算法简介 在实现文字过滤的算法中,DFA是唯一比较好的实现算法. DFA 全称为:Deterministic Finite Automaton,即确定有穷自动机.其特征为:有一个有限状态集 ...

  4. 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)

    前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...

  5. 用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)

    前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成“***”就可 ...

  6. JS采用ActiveXObject实现用户在提交表单时屏蔽敏感词的功能

    本例中敏感词ciku.txt放在C盘根目录下,采用的ActiveXObject插件获取本地文件内容.使用此插件不需网上下插件,直接用如下js代码即可. 浏览器需修改interner安全选项的级别,启用 ...

  7. Python实现屏蔽敏感词

    一.需求 1. 有一个文件,里面有一些敏感词汇,用户输入一段话,若包含这些词,就用**代替,并输出 二.实现代码 f = open('lib.txt', 'r') result = '' f1 = i ...

  8. Java实现敏感词过滤 - DFA算法

    Java实现DFA算法进行敏感词过滤 封装工具类如下: 使用前需对敏感词库进行初始化: SensitiveWordUtil.init(sensitiveWordSet); package cn.swf ...

  9. 敏感词过滤的算法原理之DFA算法

    参考文档 http://blog.csdn.net/chenssy/article/details/26961957 敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有 ...

随机推荐

  1. [LUOGU] P1111 修复公路

    题目背景 A地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地区的村庄数N,和公路数M,公路是双向的.并告诉你每条公路的连着哪两个村庄,并告诉你什么时 ...

  2. RestTemplate进行表单请求,注意要使用MultiValueMap

    在对接API的时候,有时候文档中会说,表单提交,这时候就需要用到 MultiValueMap来操作,下面给大家展示一个简单的demo. MultiValueMap<Object, Object& ...

  3. cvs 文件无法上传debug

    当时文件始终上传不成功时(一般先update后commit): cvs update filename report:move away filename ,it is in the way cvs ...

  4. GIL 线程/进程池 同步异步

    GIL 什么是GIL 全局解释器锁,本质是一把互斥锁,是加在cpython解释器上的一把锁, 同一个进程内的所有线程需要先抢到GIL锁,才能执行python代码 为什么要有GIL cpython解释器 ...

  5. js实现一个简单的响应式双向数据绑定

    一,基本原理 我们这里使用了对象中的一个特殊属性:访问器属性,这个属性不能在对象中设置,而是必须通过defineProperty()方法单独定义. 我们首先定义一个函数: var obj = { }; ...

  6. iphone丢了以后发现关机了怎么办?

    有好几个办法都可以尝试一下: 1. "ICCID法",但目前这个办法只能寻找苹果iPhone手机,而对于安卓手机,则不能采取相同的方法进行寻找.之所以能采取该方法寻找苹果 iPho ...

  7. Wp8无广告 锁屏可以持续用的手电筒

    前面的博文写了怎么实现手电筒,界面不够漂亮 我修改了界面之后 提交到了微软的App商店 在这里送上下载地址: http://www.windowsphone.com/zh-cn/store/app/% ...

  8. Linux中执行shell脚本命令的4种方法总结

    bash shell 脚本的方法有多种,现在作个小结.假设我们编写好的shell脚本的文件名为hello.sh,文件位置在/data/shell目录中并已有执行权限. 方法一:切换到shell脚本所在 ...

  9. linux的自启动服务脚本的(/etc/rc.d/init.d或者其链接/etc/init.d)

    转载地址:http://www.cnblogs.com/diyunpeng/archive/2009/11/11/1600886.html Linux有自己一套完整的启动体系,抓住了linux启动的脉 ...

  10. [BZOJ4993||4990] [Usaco2017 Feb]Why Did the Cow Cross the Road II(DP + 线段树)

    传送门 f[i][j]表示当前第i个,且最后一个位置连接到j 第一维可以省去,能连边的点可以预处理出来,dp可以用线段树优化 #include <cstdio> #include < ...