大家好,又见面了,我是你们的朋友全栈君。
项目中的需要,对用户的输入进行敏感词的过滤,使用的是DFT算法,敏感词可以从数据库进行读取和配置. 把代码整理了一下,可以直接使用 完整工程下载地址: https://download.csdn.net/download/a897180673/10278921
一共三个类,1个测试类,1个从数据库加载敏感词类,一个是实现DFT算法的类,具体的算法可以去研究.
首先是从数据库加载敏感词
package com.abc;
import com.google.common.base.Strings;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** * 加载敏感词配置文件�??<br/> * 将加载的敏感词按�?<b>DFA</b>算法的数据结构保存到{@link #wordsMap}中�??<br/> * * @author liuxinsi * @mail akalxs@gmail.com */
public class WordsLoader {
/** * 按照DFA算法的数据结构保存的敏感词�??<br/> * k=敏感词的第一个字符,v=后续字符�? */
private static final Map<String, Map> wordsMap = new HashMap<String, Map>();
static {
// 加载
List<String> wordLines = null;
try {
wordLines = loadWordsFile();
} catch (IOException e) {
e.printStackTrace();
}
addToCache(wordLines);
}
/** * 加载敏感词文件�??<br/> * 将按照顺序寻找直到找到一个�??<br/> * 1.启动时配置的系统属�?? ${swFilePath}。全路径�?<br/> * 2.${user.dir}/words.txt。一般是bin、domain etc...<br/> * 3.${classpath}/words.txt。环境变量里�?<br/> * * @return 敏感词列�? * @throws IOException */
private static List<String> loadWordsFile() throws IOException {
// 指定路径
List<String>result =new ArrayList<String>();
try {
Class.forName("com.mysql.jdbc.Driver");
Connection cnn=DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8", 数据库用户名, 数据库密码);
PreparedStatement ps=cnn.prepareStatement("select word from word");
ResultSet rs=ps.executeQuery();
while(rs.next()) {
result.add(rs.getString("word"));
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/** * 逐字分割按照DFA算法的数据结构保存敏感词至{@link #wordsMap}�?<br/> * k=敏感词的第一个字符,v=后续字符。e.g<br/> * 敏感�?=�?假发票�??<br/> * { * "�?":{"�?":{"�?":{"�?":{}}}} * } * * @param wordLines 敏感词列�? */
private static void addToCache(List<String> wordLines) {
if (wordLines == null || wordLines.isEmpty()) {
return;
}
wordLines.forEach(line -> {
if (Strings.isNullOrEmpty(line)) {
return;
}
char[] wordChars = line.toCharArray();
// 首字
String headWord = null;
// 子内�?
Map<String,Map> subWordMap = null;
for (char word : wordChars) {
String _word = String.valueOf(word);
// 第一个字�?
if (headWord == null) {
headWord = _word;
if (!wordsMap.containsKey(headWord)) {
wordsMap.put(headWord, new HashMap());
}
subWordMap = wordsMap.get(headWord);
continue;
}
// 如子内容map不包含当前字符则将当前字符保存到子中
if (!subWordMap.containsKey(_word)) {
subWordMap.put(_word, new HashMap());
subWordMap = subWordMap.get(_word);
continue;
}
// 如包含,继续去下�?个子map中寻�?
subWordMap = subWordMap.get(_word);
}
});
}
public static Map<String,Map> getWordsMap() {
return wordsMap;
}
}
第二个是敏感词检测的类
package com.abc;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/** * 敏感词检测�?? * * @author liuxinsi * @mail akalxs@gmail.com */
public class SensitiveWordsChecker {
public static Set<String> checkSensitiveWord(String textStr) {
Set<String> illWords = new HashSet<>();
Map<String, Map> wordsMap = WordsLoader.getWordsMap();
for (int i = 0; i < textStr.length(); i++) {
String currWord = String.valueOf(textStr.charAt(i));
// 如包含当前字符,则当前字符敏感,�?下找
if (wordsMap.containsKey(currWord)) {
StringBuilder strb = new StringBuilder();
strb.append(currWord);
int j = i;
// 获取当前字符的子map
Map<String, Map> subMap = wordsMap.get(currWord);
// 拼配的数�?
int matchCount = 1;
// 敏感词字符的总数�?
int wordsCount = 1;
while (true) {
// 找完�?
if (j == textStr.length() - 1) {
break;
}
// 下一个字�?
j++;
String nextWord = String.valueOf(textStr.charAt(j));
if (subMap.isEmpty()) {
break;
}
wordsCount++;
// 如子map仍然包含敏感字符接着�?下找
if (subMap.containsKey(nextWord)) {
strb.append(nextWord);
subMap = subMap.get(nextWord);
matchCount++;
}
// 已然不匹配了
if (wordsCount != matchCount) {
break;
}
}
// 如匹配的数量与敏感字符数量一致认为拼配到�?
if (matchCount == wordsCount) {
illWords.add(strb.toString());
}
}
}
return illWords;
}
}
第三个是测试类
package com.abc;
import java.util.Iterator;
import java.util.Set;
public class Test {
public static void main(String[] args) {
SensitiveWordsChecker swc=new SensitiveWordsChecker();
Set<String> ss=swc.checkSensitiveWord("这是测试文字");
Iterator<String> sencitivWord=ss.iterator();
while(sencitivWord.hasNext()) {
System.out.println(sencitivWord.next());
}
}
}
首先配置一下数据库中的表
添加一个敏感词
看一下结果:
可以看到,控制台打印出的消息.
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/139778.html原文链接:https://javaforall.cn