敏感词汇过滤(不区分大小写)
Posted qigc_0529
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了敏感词汇过滤(不区分大小写)相关的知识,希望对你有一定的参考价值。
最近项目中,用户评论内容需要屏蔽敏感词汇,从网上总结以下方法,(不区分大小写,如想设置大小写敏感,可以把代码中content..toLowerCase()去掉).具体看代码:
1.读取敏感词汇文档
<span style="font-size:18px;">package com.blemall.wizlife.util.sensitive; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; /** * @Description: 初始化敏感词库,将敏感词加入到HashMap中,构建DFA算法模型 * @Project:test * @version 1.0 */ public class SensitiveWordInit { private String ENCODING = "UTF-8"; //字符编码 @SuppressWarnings("rawtypes") public HashMap sensitiveWordMap; public SensitiveWordInit(){ super(); } @SuppressWarnings("rawtypes") public Map initKeyWord(){ try { //读取敏感词库 Set<String> keyWordSet = readSensitiveWordFile(); //将敏感词库加入到HashMap中 addSensitiveWordToHashMap(keyWordSet); //spring获取application,然后application.setAttribute("sensitiveWordMap",sensitiveWordMap); } catch (Exception e) { e.printStackTrace(); } return sensitiveWordMap; } /** * 读取敏感词库,将敏感词放入HashSet中,构建一个DFA算法模型:<br> * 中 = { * isEnd = 0 * 国 = {<br> * isEnd = 1 * 人 = {isEnd = 0 * 民 = {isEnd = 1} * } * 男 = { * isEnd = 0 * 人 = { * isEnd = 1 * } * } * } * } * 五 = { * isEnd = 0 * 星 = { * isEnd = 0 * 红 = { * isEnd = 0 * 旗 = { * isEnd = 1 * } * } * } * } * @param keyWordSet 敏感词库 * @version 1.0 */ @SuppressWarnings({ "rawtypes", "unchecked" }) private void addSensitiveWordToHashMap(Set<String> keyWordSet) { sensitiveWordMap = new HashMap(keyWordSet.size()); //初始化敏感词容器,减少扩容操作 String key = null; Map nowMap = null; Map<String, String> newWorMap = null; //迭代keyWordSet Iterator<String> iterator = keyWordSet.iterator(); while(iterator.hasNext()){ key = iterator.next(); //关键字 nowMap = sensitiveWordMap; for(int i = 0 ; i < key.length() ; i++){ char keyChar = key.charAt(i); //转换成char型 Object wordMap = nowMap.get(keyChar); //获取 if(wordMap != null){ //如果存在该key,直接赋值 nowMap = (Map) wordMap; } else{ //不存在则,则构建一个map,同时将isEnd设置为0,因为他不是最后一个 newWorMap = new HashMap<String,String>(); newWorMap.put("isEnd", "0"); //不是最后一个 nowMap.put(keyChar, newWorMap); nowMap = newWorMap; } if(i == key.length() - 1){ nowMap.put("isEnd", "1"); //最后一个 } } } } /** * 读取敏感词库中的内容,将内容添加到set集合中 * @author chenming * @date 2014年4月20日 下午2:31:18 * @return * @version 1.0 * @throws Exception */ @SuppressWarnings("resource") private Set<String> readSensitiveWordFile() throws Exception{ Set<String> set = null; ClassLoader loader=SensitiveWordInit.class.getClassLoader(); URL url=loader.getResource("/SensitiveWord.txt"); String filePath =url.getPath(); File file=new File(filePath); InputStreamReader read = new InputStreamReader(new FileInputStream(file),ENCODING); try { if(file.isFile() && file.exists()){ //文件流是否存在 set = new HashSet<String>(); BufferedReader bufferedReader = new BufferedReader(read); String txt = null; while((txt = bufferedReader.readLine()) != null){ //读取文件,将文件内容放入到set中 set.add(txt); } } else{ //不存在抛出异常信息 throw new Exception("敏感词库文件不存在"); } } catch (Exception e) { throw e; }finally{ read.close(); //关闭文件流 } return set; } } </span>2.具体方法:
replaceSensitiveWord(String content(内容),int matchType(匹配规则),String replaceChar(替换词))
<span style="font-size:18px;">package com.blemall.wizlife.util.sensitive; import org.springframework.stereotype.Component; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; @Component public class SensitivewordFilter { @SuppressWarnings("rawtypes") private Map sensitiveWordMap = null; public static int minMatchTYpe = 1; //最小匹配规则 public static int maxMatchType = 2; //最大匹配规则 /** * 构造函数,初始化敏感词库 */ public SensitivewordFilter(){ sensitiveWordMap = new SensitiveWordInit().initKeyWord(); } /** * 判断文字是否包含敏感字符 * @param txt 文字 * @param matchType 匹配规则 1:最小匹配规则,2:最大匹配规则 * @return 若包含返回true,否则返回false * @version 1.0 */ public boolean isContaintSensitiveWord(String txt,int matchType){ boolean flag = false; for(int i = 0 ; i < txt.length() ; i++){ int matchFlag = this.CheckSensitiveWord(txt, i, matchType); //判断是否包含敏感字符 if(matchFlag > 0){ //大于0存在,返回true flag = true; } } return flag; } /** * 获取文字中的敏感词 * @param txt 文字 * @param matchType 匹配规则 1:最小匹配规则,2:最大匹配规则 * @return * @version 1.0 */ public Set<String> getSensitiveWord(String txt , int matchType){ Set<String> sensitiveWordList = new HashSet<String>(); for(int i = 0 ; i < txt.length() ; i++){ int length = CheckSensitiveWord(txt, i, matchType); //判断是否包含敏感字符 if(length > 0){ //存在,加入list中 sensitiveWordList.add(txt.substring(i, i+length)); i = i + length - 1; //减1的原因,是因为for会自增 } } return sensitiveWordList; } /** * @date 2014年4月20日 下午5:12:07 * @param content * @param matchType * @param replaceChar 替换字符,默认* * @version 1.0 */ public String replaceSensitiveWord(String content,int matchType,String replaceChar){ String resultTxt = content; Set<String> set = getSensitiveWord(content.toLowerCase(), matchType);//将输入内容先转换为小写,获取所有的敏感词 Iterator<String> iterator = set.iterator(); String word = null; String replaceString = null; while (iterator.hasNext()) { word = iterator.next(); word="(?i)"+word; replaceString = getReplaceChars(replaceChar, word.length()); resultTxt = resultTxt.replaceAll(word, replaceString); } return resultTxt; } /** * 获取替换字符串 * @param replaceChar * @param length * @return * @version 1.0 */ private String getReplaceChars(String replaceChar,int length){ String resultReplace = replaceChar; for(int i = 1 ; i < length ; i++){ resultReplace += replaceChar; } return resultReplace; } /** * 检查文字中是否包含敏感字符,检查规则如下:<br> * @param txt * @param beginIndex * @param matchType * @return,如果存在,则返回敏感词字符的长度,不存在返回0 * @version 1.0 */ @SuppressWarnings({ "rawtypes"}) public int CheckSensitiveWord(String txt,int beginIndex,int matchType){ boolean flag = false; //敏感词结束标识位:用于敏感词只有1位的情况 int matchFlag = 0; //匹配标识数默认为0 char word = 0; Map nowMap = sensitiveWordMap; for(int i = beginIndex; i < txt.length() ; i++){ word = txt.charAt(i); nowMap = (Map) nowMap.get(word); //获取指定key if(nowMap != null){ //存在,则判断是否为最后一个 matchFlag++; //找到相应key,匹配标识+1 if("1".equals(nowMap.get("isEnd"))){ //如果为最后一个匹配规则,结束循环,返回匹配标识数 flag = true; //结束标志位为true if(SensitivewordFilter.minMatchTYpe == matchType){ //最小规则,直接返回,最大规则还需继续查找 break; } } } else{ //不存在,直接返回 break; } } if(matchFlag < 2 || !flag){ //长度必须大于等于1,为词 matchFlag = 0; } return matchFlag; } } </span>附件:敏感词汇表(SensitiveWord.txt)
以上是关于敏感词汇过滤(不区分大小写)的主要内容,如果未能解决你的问题,请参考以下文章