2.2.2 关键字过滤类/** * Created On : 2022/7/26. * <p> * Author : zhukang * <p> * Description: 敏感字过滤工具类 */@Componentpublic class SensitiveWordFilterUtil { // 最小匹配规则 public static final int MIN_MATCH_TYPE = 1; // 最大匹配规则 public static final int MAX_MATCH_TYPE = 2; // 敏感词集合 public static Map sensitiveWordMap; // 应用启动后,创建实例对象,自动执行此方法 @PostConstruct public void init() { // 从数据库查询敏感词,转换为set集合 将敏感词库加入到HashMap中,确定有穷自动机DFA sensitiveWordMap = new com.kgc.weddingshop.utils.SensitiveWordInit().initSensitiveWord(); System.out.println("------ " + sensitiveWordMap + "------"); } /** * @param : [java.lang.String] * @return : boolean true 包含;false 不包含 * @author : zhukang * @date : 2022/7/26 * @description : 是否包含敏感词(默认按最小匹配规则来,只要有敏感词就ok),最小匹配规则 */ public boolean isContainSensitiveWordMin(String txt) { return isContainSensitiveWord(txt, MIN_MATCH_TYPE); } /** * @param : [java.lang.String, int] * @return : boolean * @author : zhukang * @date : 2022/7/26 * @description : 是否包含敏感词(默认按指定匹配规则来,只要有敏感词就ok) * 如果敏感词库为: * * 傻叉 * * 傻叉人 * * 大傻叉 * * 初始化之后为:{傻={叉={人={isEnd=1}, isEnd=1}, isEnd=0}, 大={傻={叉={isEnd=1}, isEnd=0}, isEnd=0}} * * 1、按最小规则匹配, 匹配 傻叉 的时候,匹配到叉,就为最后一个了 直接break 。如果输入的敏感词是傻叉人,命中的只是傻叉,而不是傻叉人 * * 2、按最大规则匹配, 匹配 傻叉 的时候,匹配到叉,已经为最后一个,但是按照最大规则,会继续匹配人,命中的是傻叉人 * * 3、如果关键词是傻叉猫,两种匹配规则都会匹配到傻叉,会命中,如果输入的是傻叉人猫,按最小规则匹配是傻叉,按最大规则匹配傻叉人,只是匹配敏感词不同 */ public boolean isContainSensitiveWord(String txt, int matchType) { if (txt == null || "".equals(txt)) { return false; } for (int i = 0; i < txt.length(); i++) { int matchFlag = this.checkSensitiveWords(txt, i, matchType); if (matchFlag > 0) { return true; } } return false; } /** * @param : 待判断文本 起始位置 匹配类型: 1 最小匹配原则;2 最大匹配原则 * @return : int 大于0表示包含敏感词且表示敏感词匹配长度,否则不包含 * @author : zhukang * @date : 2022/7/26 * @description : 校验是否包含敏感词 */ private static int checkSensitiveWords(String txt, int beginIndex, int matchType) { // 敏感词结束标识位:用于敏感词只有1位的情况 boolean flag = false; // 匹配标识数默认为0 int matchFlag = 0; // 从内存中,获取敏感词库 Map nowMap = sensitiveWordMap; for (int i = beginIndex; i < txt.length(); i++) { // 获取第一个字符 char word = txt.charAt(i); // 获取指定key,判断当前字符是不是一个敏感词的开头 nowMap = (Map) nowMap.get(word); // 不存在,直接返回 if (nowMap == null) { break; } // 根据排列组合的匹配,如果出现在敏感词库中,即找到相应key,匹配标识+1 matchFlag++; // 如果已经匹配到词库中完整的敏感词, 改匹配结束标识,并根据匹配规则判断,是否继续 if ("1".equals(nowMap.get("isEnd"))) { // 结束标志位为true,已经命中到了一个完整敏感词 flag = true; // 最小规则,直接返回, 最大规则还需继续查找 if (matchType == MIN_MATCH_TYPE) { break; } } } // 长度必须大于等于1,为词,敏感词只有1个字的情况 if (matchFlag < 2 || !flag) { matchFlag = 0; } return matchFlag; } /** * @param : txt 待判断文本 * @return : 匹配类型: 1 最小匹配原则;2 最大匹配原则 * @author : zhukang * @date : 2022/7/26 * @description : 获取匹配的敏感词 */ public Set<String> getSensitiveWords(String txt, Integer matchType) { Set<String> sensitiveWords = new HashSet<>(); for (int i = 0; i < txt.length(); i++) { Integer length = checkSensitiveWords(txt, i, matchType); if (length > 0) { sensitiveWords.add(txt.substring(i, i + length)); // 循环i会+1,所以需-1 i = i + length - 1; } } return sensitiveWords; } /** * @param : txt,文本 matchType 匹配类型: 1 最小匹配原则;2 最大匹配原则 * @return : 替换字符 * @author : zhukang * @date : 2022/7/26 * @description : 替换敏感词 */ public String replaceSensitiveWords(String txt, Integer matchType, String replaceStr) { if (txt == null || "".equals(txt)) { return txt; } // 获取所有敏感词 Set<String> sensitiveWords = getSensitiveWords(txt, matchType); Iterator<String> iterator = sensitiveWords.iterator(); String replaceString = ""; while (iterator.hasNext()) { String sWord = iterator.next(); replaceString = getReplaceString(replaceStr, sWord.length()); txt = txt.replaceAll(sWord, replaceString); } return txt; } /** * @param : replaceStr 替换字符 * @return : 敏感字长度 * @author : zhukang * @date : 2022/7/26 * @description : 替换为指定字符,没有指定替换字符,默认* */ private static String getReplaceString(String replaceStr, Integer length) { // 指定替换字符为* if (replaceStr == null) { replaceStr = "*"; } // 可变字符串对象 StringBuffer replaceString = new StringBuffer(); // 循环遍历,替换内容 for (int i = 0; i < length; i++) { replaceString.append(replaceStr); } return replaceString.toString(); }}
经验总结扩展阅读
- 世界上的五大人种
- 佐助五影会谈第几集
- 动森五一活动迷宫攻略
- 支付宝蚂蚁庄园10月28日答提分享
- 主力建仓时的五大特征是什么
- 四大名山和五岳在哪
- 支付宝蚂蚁庄园10月28日答案是什么
- 如何删除支付宝的帐户明细
- 王者荣耀五杀限制时间是多久
- 如何制作梅干菜扣肉烧饼
