一、敏感词过滤数据文件
https://github.com/jkiss/sensitive-words
代码图数据文件如下:
二、敏感词实现原理基于二叉树排序
首先:query 日 ---> {本}、query 本 --->{人、鬼子}、query 人 --->{null}、query 鬼 ---> {子}。形如下结构:
三、敏感词过滤代码
封装工具类如下:
使用前需对敏感词库进行初始化: SensitiveWordUtil.init(sensitiveWordSet);
package cn.swfilter.util;
import java.util.*;/**
* 敏感词处理工具 - DFA算法实现
*
* @author sam
* @since 2017/9/4
*/
public class SensitiveWordUtil { /** * 敏感词匹配规则 */ public static final int MinMatchTYpe = 1; //最小匹配规则,如:敏感词库["中国","中国人"],语句:"我是中国人",匹配结果:我是[中国]人 public static final int MaxMatchType = 2; //最大匹配规则,如:敏感词库["中国","中国人"],语句:"我是中国人",匹配结果:我是[中国人] /** * 敏感词集合 */ public static HashMap sensitiveWordMap; /** * 初始化敏感词库,构建DFA算法模型 * * @param sensitiveWordSet 敏感词库 */ public static synchronized void init(Set<String> sensitiveWordSet) { initSensitiveWordMap(sensitiveWordSet); } /** * 初始化敏感词库,构建DFA算法模型 * * @param sensitiveWordSet 敏感词库 */ private static void initSensitiveWordMap(Set<String> sensitiveWordSet) { //初始化敏感词容器,减少扩容操作 sensitiveWordMap = new HashMap(sensitiveWordSet.size()); String key; Map nowMap; Map<String, String> newWorMap; //迭代sensitiveWordSet Iterator<String> iterator = sensitiveWordSet.iterator(); while (iterator.hasNext()) { //关键字 key = iterator.next(); nowMap = sensitiveWordMap; for (int i = 0; i < key.length(); i++) { //转换成char型 char keyChar = key.charAt(i); //库中获取关键字 Object wordMap = nowMap.get(keyChar); //如果存在该key,直接赋值,用于下一个循环获取 if (wordMap != null) { nowMap = (Map) wordMap; } else { //不存在则,则构建一个map,同时将isEnd设置为0,因为他不是最后一个 newWorMap = new HashMap<>(); //不是最后一个 newWorMap.put("isEnd", "0"); nowMap.put(keyChar, newWorMap); nowMap = newWorMap; } if (i == key.length() - 1) { //最后一个 nowMap.put("isEnd", "1"); } } } } /** * 判断文字是否包含敏感字符 * * @param txt 文字 * @param matchType 匹配规则 1:最小匹配规则,2:最大匹配规则 * @return 若包含返回true,否则返回false */ public static boolean contains(String txt, int matchType) { boolean flag = false; for (int i = 0; i < txt.length(); i++) { int matchFlag = checkSensitiveWord(txt, i, matchType); //判断是否包含敏感字符 if (matchFlag > 0) { //大于0存在,返回true flag = true; } } return flag; } /** * 判断文字是否包含敏感字符 * * @param txt 文字 * @return 若包含返回true,否则返回false */ public static boolean contains(String txt) { return contains(txt, MaxMatchType); } /** * 获取文字中的敏感词 * * @param txt 文字 * @param matchType 匹配规则 1:最小匹配规则,2:最大匹配规则 * @return */ public static Set<String> getSensitiveWord(String txt, int matchType) { Set<String> sensitiveWordList = new HashSet<>(); for (int i = 0; i < txt.length(); i++) { //判断是否包含敏感字符 int length = checkSensitiveWord(txt, i, matchType); if (length > 0) {