参考文章:https://blog.csdn.net/chenssy/article/details/26961957
补充说明:
1.具体的DFA介绍参考原文章,此处只是补充了文章中没有介绍的点以及根据实际需求进行了改造
2.最大/小匹配规则:比如说存在两个敏感词[abc,ab],最大规则匹配中abc,最小匹配规则匹配中ab
3.添加自动忽略特殊字符的功能
/**
* 判断是否是要忽略的字符(忽略所有特殊字符以及空格)
* @param specificChar 指定字符
* @return 特殊字符或空格true否则false
*/
private boolean isIgnore(char specificChar){
String regex = "[`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]|\\s*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(String.valueOf(specificChar));
return matcher.matches();
}
--------------------------------------------------------分隔线---------------------------------------------------------------------
20191227更新:此处使用正则表达式可以进行优化,正则表达式优化主要是要减少回溯次数,具体可参考下述文章
https://www.cnblogs.com/softidea/p/9552080.html
优化函数代码:
/**
* 忽略特殊字符的正则表达式MATCHER
*/
private final Matcher IGNORE_MATCHER = Pattern.compile(IGNORE_SPECIAL_CHAR_REGEX).matcher("");
/**
* 判断是否是要忽略的字符(忽略所有特殊字符以及空格)
*
* @param specificChar 指定字符
* @return 特殊字符或空格true否则false
*/
private boolean isIgnore(char specificChar) {
return IGNORE_MATCHER.reset(String.valueOf(specificChar)).matches();
}
--------------------------------------------------------分隔线---------------------------------------------------------------------
实际业务需求:
一堆敏感词文件,一个词一行,把目录下的所有敏感词文件在启动项目的时候加载进去,并且提供匹配敏感词的方法
优化点:
做到不重启应用更新敏感词库,这个需要进行对敏感词文件的动态监控,然后发生变化后更新DFA树,有时间再研究
实现代码(采用springboot方式实现,其实就是java,但是用的springboot的@PostConstruct注解在启动前加载敏感词库):