KeyTree类 这个类的功能是 :
读取硬盘上的key.txt(里面存放的是敏感关键词),将之读入Set中,再讲Set中的元素传入到Map中(通过Map来生成敏感词的树状结构),并传出这个Map(敏感词树)
public Map createKeyWord():创建一个Map类型的词库(敏感词树)
private void readSetToMap(Set<String> keyWordSet): (内部方法)读取敏感词库,将敏感词放入HashSet中
private Set<String> readKeyTxt():(内部方法)读取敏感词库中的内容,将内容添加到set集合中
1 package pingbi;
2
3 /**
4 * keyWordSet:敏感词集合(中间量) 将原始key.txt中的内容先读入到这个变量(keyWordSet)中,
5 * 再由此变量生成敏感词树(keyTreeMap)
6 * newMap、nowMap:一起用来生成敏感词树(keyTreeMap)的
7 * keyTreeMap:敏感词树
8 */
9 import java.io.BufferedReader;
10 import java.io.File;
11 import java.io.FileInputStream;
12 import java.io.InputStreamReader;
13 import java.util.*;
14
15 /** ----------------初始化敏感词库,将敏感词加入到HashMap中,构建DFA算法模型-----------------*/
16 public class KeyTree {
17 // private String ENCODING = "GBK"; //字符编码
18 private String ENCODING = "UTF-8"; // 字符编码
19 @SuppressWarnings("rawtypes")
20 private HashMap keyTreeMap;// 敏感词集合
21
22 public HashMap getKeyTreeMap() {
23 return keyTreeMap;
24 }
25
26 @SuppressWarnings("rawtypes")
27 public Map createKeyWord() {
28 try {
29 // 读取敏感词库
30 Set<String> keyWordSet = readKeyTxt();
31 // 将敏感词库加入到HashMap中
32 readSetToMap(keyWordSet);
33 // spring获取application,然后application.setAttribute("sensitiveWordMap",sensitiveWordMap);
34 } catch (Exception e) {
35 e.printStackTrace();
36 }
37 return keyTreeMap;
38 }
39
40 /*-------------- 读取敏感词库,将敏感词放入HashSet中,构建一个DFA算法模型--------------*/
41 @SuppressWarnings({ "rawtypes", "unchecked" })
42 private void readSetToMap(Set<String> keyWordSet) {
43 keyTreeMap = new HashMap(keyWordSet.size());// 初始化敏感词容器,减少扩容操作
44 String key = null;
45 Map nowMap = null;
46 Map<String, String> newMap = null;
47 // 迭代keyWordSet
48 Iterator<String> iterator = keyWordSet.iterator();
49 while (iterator.hasNext()) {
50 key = iterator.next(); // 关键字
51 nowMap = keyTreeMap;
52 for (int i = 0; i < key.length(); i++) {
53 char keyChar = key.charAt(i); // 转换成char型
54 Object wordMap = nowMap.get(keyChar); // 获取
55
56 if (wordMap != null) { // 如果存在该key,直接赋值
57 nowMap = (Map) wordMap;
58 } else { // 不存在则,则构建一个map,同时将isEnd设置为0,因为他不是最后一个
59 newMap = new HashMap<String, String>();
60 newMap.put("isEnd", "0"); // 不是最后一个
61 nowMap.put(keyChar, newMap);
62 nowMap = newMap;
63 }
64
65 if (i == key.length() - 1) {
66 nowMap.put("isEnd", "1"); // 最后一个
67 }
68 }
69 }
70 }
71
72 /*------------------- 读取敏感词库中的内容,将内容添加到set集合中--------------------*/
73 @SuppressWarnings("resource")
74 private Set<String> readKeyTxt() throws Exception {
75 Set<String> set = null;
76
77 String filepath = "E:\\pingbi\\key.txt";
78 File file = new File(filepath); // 读取文件
79 // String filename = "key.txt";
80
81 InputStreamReader read = new InputStreamReader(new FileInputStream(filepath), ENCODING);
82 try {
83 if (file.isFile() && file.exists()) {// 文件流是否存在
84 set = new HashSet<String>();
85 BufferedReader bufferedReader = new BufferedReader(read);
86 String txt;
87 while ((txt = bufferedReader.readLine()) != null) {// 读取文件,将文件内容放入到set中
88 set.add(txt);
89 }
90 } else {// 不存在抛出异常信息
91 throw new Exception("敏感词库文件不存在");
92 }
93 } catch (Exception e) {
94 throw e;
95 } finally {
96 read.close();// 关闭文件流
97 }
98 return set;
99 }
100 }
shieldUtil类提供 工具方法
public shieldUtil(): 构造方法,初始化敏感词库
public Set<String> getSensitiveWord(String txt): 获取文字中所有的的敏感词,并放入一个Set中
public String replaceSensitiveWord(String txt, String replaceChar): 替换敏感字字符,替换字符,默认
public int CheckSensitiveWord(String txt, int beginIndex) :检查文字中是否包含敏感字符,检查规则如下: 如果存在,则返回敏感词字符的长度,不存在返回0
public boolean isSensitive(String txt): 判断是否含有敏感词
private String getReplaceChars(String replaceChar, int length): (内部方法)获取替换字符串
1 package pingbi;
2
3 import java.io.*;
4 import java.util.HashSet;
5 import java.util.Iterator;
6 import java.util.Map;
7 import java.util.Set;
8
9 /** 敏感词过滤 */
10 public class shieldUtil {
11 @SuppressWarnings("rawtypes")
12 private Map keyWord= null;// 树
13
14 /* -------------------构造函数,初始化敏感词库-------------------------- */
15 public shieldUtil() {
16 keyWord= new KeyTree().createKeyWord();
17 }
18
19 /*--------------- 获取文字中所有的的敏感词,并放入一个Set中--------------------*/
20 public Set<String> getSensitiveWord(String txt) {
21 Set<String> sensitiveWordSet = new HashSet<String>();
22
23 for (int i = 0; i < txt.length(); i++) {
24 int length = CheckSensitiveWord(txt, i);// 判断是否包含敏感字符
25 if (length > 0) {// 存在,加入list中
26 sensitiveWordSet.add(txt.substring(i, i + length));
27 i = i + length - 1;// 减1的原因,是因为for会自增
28 }
29 }
30 return sensitiveWordSet;
31 }
32
33 /*------------------替换敏感字字符,替换字符,默认------------------*/
34 public String replaceSensitiveWord(String txt, String replaceChar) {
35 String resultTxt = txt;
36 Set<String> set = getSensitiveWord(txt); // 获取所有的敏感词
37 Iterator<String> iterator = set.iterator();
38 String word = null;
39 String replaceString = null;
40 while (iterator.hasNext()) {
41 word = iterator.next();
42 replaceString = getReplaceChars(replaceChar, word.length());
43 resultTxt = resultTxt.replaceAll(word, replaceString);
44 }
45 return resultTxt;
46 }
47
48 /*-----------------获取替换字符串 -----------------*/
49 /* 例如,已知匹配到的敏感词长度是3,想要替换成“*”号,则得到的替换字符串为“***” */
50 private String getReplaceChars(String replaceChar, int length) {
51 String resultReplace = replaceChar;
52 for (int i = 1; i < length; i++) {
53 resultReplace += replaceChar;
54 }
55 return resultReplace;
56 }
57
58 /*--------检查文字中是否包含敏感字符,检查规则如下: 如果存在,则返回敏感词字符的长度,不存在返回0---------*/
59 // 只匹配一次,成功即返回
60 @SuppressWarnings({ "rawtypes" })
61 public int CheckSensitiveWord(String txt, int beginIndex) {
62 boolean flag = false;// 敏感词结束标识位:用于敏感词只有1位的情况
63 int matchLength = 0;// 匹配标识数默认为0
64 char word = 0;
65 Map nowMap = keyWord;
66 for (int i = beginIndex; i < txt.length(); i++) {
67 word = txt.charAt(i);
68 nowMap = (Map) nowMap.get(word);// 获取指定key
69 if (nowMap != null) {// 存在,则判断是否为最后一个
70 matchLength++;// 找到相应key,匹配标识+1
71 if ("1".equals(nowMap.get("isEnd"))) {// 如果为最后一个匹配规则,结束循环,返回匹配标识数
72 flag = true;// 结束标志位为true
73 }
74 } else {// 不存在,直接返回
75 break;
76 }
77 }
78 if (matchLength < 2 || !flag) {// 长度必须大于等于1,为词
79 matchLength = 0;
80 }
81 return matchLength;
82 }
83
84 /*----------------------判断是否含有敏感词------------------*/
85 public boolean isSensitive(String txt) {
86 int matchLength = CheckSensitiveWord(txt, 0);
87 return matchLength > 0;
88 }
89 }
来源:https://www.cnblogs.com/dayuruozhi/p/6610588.html