这里主要讲敏感词过滤与替换两个功能,引入相关maven依赖
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.apache.commons
commons-lang3
3.12.0
敏感词文本文件放在resources/static
目录,取名为Sensitive.txt,敏感词文本网上很多,这里就随便贴一个:
- https://github.com/lining0806/TextFilter/blob/master/敏感词库大全.txt
简单原理如下图,使用了DFA算法,创建一个HashMap,哈希里key值存储的是敏感词的一个词,value指向下一个结点(即指向下一个词),一个哈希表中可以存放多个值,比如赌博、赌黄这两个都是敏感词。
首先我们要进行敏感词库的初始化,在内存中构建好敏感词的Map节点!
@Configuration
public class WordInit {
// 字符编码
private String ENCODING = "UTF-8";
// 初始化敏感字库
public Map initKeyWord() throws IOException {
// 读取敏感词库 ,存入Set中
Set wordSet = readSensitiveWordFile();
// 将敏感词库加入到HashMap中//确定有穷自动机DFA
return addSensitiveWordToHashMap(wordSet);
}
// 读取敏感词库 ,存入HashMap中
private Set readSensitiveWordFile() throws IOException {
Set wordSet = null;
ClassPathResource classPathResource = new ClassPathResource("static/word.txt");
InputStream inputStream = classPathResource.getInputStream();
//敏感词库
try {
// 读取文件输入流
InputStreamReader read = new InputStreamReader(inputStream, ENCODING);
// 文件是否是文件 和 是否存在
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();
// 关闭文件流
read.close();
}服务器托管网 catch (Exception e) {
e.printStackTrace();
}
return wordSet;
}
// 将HashSet中的敏感词,存入HashMap中
private Map addSensitiveWordToHashMap(Set wordSet) {
// 初始化敏感词容器,减少扩容操作
Map wordMap = new HashMap(wordSet.size());
for (String word : wordSet) {
Map nowMap = wordMap;
for (int i = 0; i newMap = new HashMap();
newMap.put("isEnd", "0");
// 添加到集合
nowMap.put(keyChar, newMap);
nowMap = newMap;
}
// 最后一个
if (i == word.length() - 1) {
nowMap.put("isEnd", "1");
}
}
}
return wordMap;
}
}
接着创建一个敏感词过滤器,主要功能敏感词的过滤以及替换
@Component
public class SensitiveFilter {
/**
* 敏感词过滤器:利用DFA算法 进行敏感词过滤
*/
private Map sensitiveWordMap = null;
/**
* 最小匹配规则,如:敏感词库["中国","中国人"],语句:"我是中国人",匹配结果:我是[中国]人
*/
public static int minMatchType = 1;
/**
* 最大匹配规则,如:敏感词库["中国","中国人"],语句:"我是中国人",匹配结果:我是[中国人]
*/
public static int maxMatchType = 2;
/**
* 敏感词替换词
*/
public static String placeHolder = "**";
// 单例
private static SensitiveFilter instance = null;
/**
* 构造函数,初始化敏感词库
*/
private SensitiveFilter() throws IOException {
sensitiveWordMap = new SensitiveWordInit().initKeyWord();
}
/**
* 获取单例
*/
public static SensitiveFilter getInstance() throws IOException {
if (null == instance) {
instance = new SensitiveFilter();
}
return instance;
}
/**
* 获取文字中的敏感词
*/
public Set getSensitiveWord(String t服务器托管网xt, int matchType) {
Set sensitiveWordList = new HashSet();
for (int i = 0; i 0) {
sensitiveWordList.add(txt.substring(i, i + length));
// 减1的原因,是因为for会自增
i = i + length - 1;
}
}
return sensitiveWordList;
}
/**
* 替换敏感字字符,使用了默认的替换符合,默认最小匹配规则
*/
public String replaceSensitiveWord(String txt) {
return replaceSensitiveWord(txt, minMatchType ,placeHolder);
}
/**
* 替换敏感字字符,使用了默认的替换符合
*/
public String replaceSensitiveWord(String txt, int matchType) {
return replaceSensitiveWord(txt, matchType,placeHolder);
}
/**
* 替换敏感字字符
*/
public 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;
}
/**
* 获取替换字符串
*/
private String getReplaceChars(String replaceChar, int length) {
StringBuilder resultReplace = new StringBuilder(replaceChar);
for (int i = 1; i
* 如果存在,则返回敏感词字符的长度,不存在返回0
* 核心
*/
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
最后进行测试!!
@RestController
public class Controller {
private static Logger logger = LoggerFactory.getLogger(SensitiveController.class);
@Autowired
SensitiveFilter sensitiveFilter;
@GetMapping("/sensitive")
public String sensitive(String keyword){
String s = sensitiveFilter.replaceSensitiveWord(keyword);
return s;
}
}
最后说一句(求关注!)
如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。
关注公众号:woniuxgg,在公众号中回复:笔记就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net