demo目录结构:

35d4c583c89e4523e0fca74710d2343e.png

文档内容格式:

0c036876a1472938182640ac8d62afa1.png

直接上代码(检索敏感词算法是从网上搜集参考的,有想法的可以搜索DFA算法研究下):

SensitiveFilterService.java

package com.example.sensitivedemo.test;

/**

* @Author : JCccc

* @CreateTime : 2019/7/30

* @Description :

**/

import java.util.HashSet;

import java.util.Iterator;

import java.util.Map;

import java.util.Set;

//敏感词过滤器:利用DFA算法  进行敏感词过滤

@SuppressWarnings(“rawtypes”)

public class SensitiveFilterService {

private Map sensitiveWordMap = null;

// 最小匹配规则

public static int minMatchTYpe = 1;

// 最大匹配规则

public static int maxMatchType = 2;

// 单例

private static SensitiveFilterService instance = null;

// 构造函数,初始化敏感词库

private SensitiveFilterService() {

sensitiveWordMap = new SensitiveWordInit().initKeyWord();

}

// 获取单例

public static SensitiveFilterService getInstance() {

if (null == instance) {

instance = new SensitiveFilterService();

}

return instance;

}

// 获取文字中的敏感词

public SetgetSensitiveWord(String txt, int matchType) {

SetsensitiveWordList = new HashSet();

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;

}

// 替换敏感字字符

public String replaceSensitiveWord(String txt, int matchType,

String replaceChar) {

String resultTxt = txt;

// 获取所有的敏感词

Setset = getSensitiveWord(txt, matchType);

Iteratoriterator = 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;

}

/**

* 检查文字中是否包含敏感字符,检查规则如下:

* 如果存在,则返回敏感词字符的长度,不存在返回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 (SensitiveFilterService.minMatchTYpe == matchType) {

break;

}

}

}

// 不存在,直接返回

else {

break;

}

}

if (matchFlag < 2 && !flag) { // 长度必须大于等于1,为词

matchFlag = 0;

}

return matchFlag;

}

}

SensitiveWordInit.java

package com.example.sensitivedemo.test;

/**

* @Author : JCccc

* @CreateTime : 2019/7/30

* @Description :

**/

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;

//屏蔽敏感词初始化

@SuppressWarnings({ “rawtypes”, “unchecked” })

public class SensitiveWordInit {

// 字符编码

private String ENCODING = “UTF-8”;

// 初始化敏感字库

public Map initKeyWord() {

// 读取敏感词库 ,存入Set中

SetwordSet = readSensitiveWordFile();

// 将敏感词库加入到HashMap中//确定有穷自动机DFA

return addSensitiveWordToHashMap(wordSet);

}

/**

* 读取敏感词库,将敏感词放入HashSet中,构建一个DFA算法模型:

* 中 = {

*      isEnd = 0

*      国 = {

*           isEnd = 1

*           人 = {isEnd = 0

*                民 = {isEnd = 1}

*                }

*           男  = {

*                  isEnd = 0

*                   人 = {

*                        isEnd = 1

*                       }

*               }

*           }

*      }

*  五 = {

*      isEnd = 0

*      星 = {

*          isEnd = 0

*          红 = {

*              isEnd = 0

*              旗 = {

*                   isEnd = 1

*                  }

*              }

*          }

*      }

* @author 孙创   感谢作者

* @date 2017年2月15日 下午3:20:20

* @param keyWordSet  敏感词库

*/

// 读取敏感词库 ,存入HashMap中

private SetreadSensitiveWordFile() {

SetwordSet = null;

// app为项目地址

/*

* String app = System.getProperty(“user.dir”); System.out.println(app);

* URL resource = Thread.currentThread().getContextClassLoader()

* .getResource(“/”); String path = resource.getPath().substring(1);

* System.out.println(path); File file = new File(path +

* “censorwords.txt”);

*/

//敏感词库

File file = new File(

“E:\\sensitivedemo\\src\\main\\resources\\static\\censorwords.txt”);

try {

// 读取文件输入流

InputStreamReader read = new InputStreamReader(new FileInputStream(

file), ENCODING);

// 文件是否是文件 和 是否存在

if (file.isFile() && file.exists()) {

wordSet = new HashSet();

// StringBuffer sb = new StringBuffer();

// BufferedReader是包装类,先把字符读到缓存里,到缓存满了,再读入内存,提高了读的效率。

BufferedReader br = new BufferedReader(read);

String txt = null;

// 读取文件,将文件内容放入到set中

while ((txt = br.readLine()) != null) {

wordSet.add(txt);

}

br.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;

}

// 将HashSet中的敏感词,存入HashMap中

private Map addSensitiveWordToHashMap(SetwordSet) {

// 初始化敏感词容器,减少扩容操作

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 {

// 设置标志位

MapnewMap = new HashMap();

newMap.put(“isEnd”, “0”);

// 添加到集合

nowMap.put(keyChar, newMap);

nowMap = newMap;

}

// 最后一个

if (i == word.length() – 1) {

nowMap.put(“isEnd”, “1”);

}

}

}

return wordMap;

}

}

测试 Main.java:

package com.example.sensitivedemo.test;

/**

* @Author : JCccc

* @CreateTime : 2019/7/30

* @Description :

**/

public class Main {

public static void main(String[] args) {

//需要屏蔽哪些字就在censorword.txt文档内添加即可

SensitiveFilterService filter = SensitiveFilterService.getInstance();

String txt = “xx需要进行检测的字符串xxx”;

//如果需要过滤则用“”替换

//如果需要屏蔽,则用“*”替换

String hou = filter.replaceSensitiveWord(txt, 1, “*”);

System.out.println(“替换前的文字为:” + txt);

System.out.println(“替换后的文字为:” + hou);

}

}

到此