关键词过滤
關鍵詞庫創建思路:采用二叉樹
實現代碼:
1.關鍵詞庫初始化:
package com.slince.test2;import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; 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* @Author : chenming * @Date : 2014年4月20日 下午2:27:06 * @version 1.0 */ public class SensitiveWordInit {private String ENCODING = "GBK"; //字符編碼 @SuppressWarnings("rawtypes")public HashMap sensitiveWordMap;public SensitiveWordInit(){super();}/** * @author chenming * @date 2014年4月20日 下午2:28:32 * @version 1.0 */ @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 * } * } * } * } * @author chenming * @date 2014年4月20日 下午3:04:20 * @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;File file = new File("D:\\SensitiveWord.txt"); //讀取文件 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;} }2.關鍵詞檢索和測試:
package com.slince.test2;import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set;/** * @Description: 敏感詞過濾 * @Project:test* @Author : chenming * @Date : 2014年4月20日 下午4:17:15 * @version 1.0 */ 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();}/** * 判斷文字是否包含敏感字符 * @author chenming * @date 2014年4月20日 下午4:28:30 * @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;}/** * 獲取文字中的敏感詞 * @author chenming * @date 2014年4月20日 下午5:10:52 * @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;}/** * 替換敏感字字符 * @author chenming * @date 2014年4月20日 下午5:12:07 * @param txt * @param matchType * @param replaceChar 替換字符,默認* * @version 1.0 */ public String replaceSensitiveWord(String txt,int matchType,String replaceChar){String resultTxt = txt;Set<String> set = getSensitiveWord(txt, matchType); //獲取所有的敏感詞 Iterator<String> iterator = set.iterator();String word = null;String replaceString = null;while (iterator.hasNext()) {word = iterator.next();replaceString = getReplaceChars(replaceChar, word.length());resultTxt = resultTxt.replaceAll(word, replaceString);}return resultTxt;}/** * 獲取替換字符串 * @author chenming * @date 2014年4月20日 下午5:21:19 * @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> * @author chenming * @date 2014年4月20日 下午4:31:03 * @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;}public static void main(String[] args) {SensitivewordFilter filter = new SensitivewordFilter();System.out.println("敏感詞的數量:" + filter.sensitiveWordMap.size());String string = "老虎機,游戲機,假幣,毛澤東";System.out.println("待檢測語句字數:" + string.length());long beginTime = System.currentTimeMillis();Set<String> set = filter.getSensitiveWord(string, 1);long endTime = System.currentTimeMillis();System.out.println("語句中包含敏感詞的個數為:" + set.size() + "。包含:" + set);System.out.println("總共消耗時間為:" + (endTime - beginTime));} } 3.加載的關鍵詞庫的格式:簡單文本格式(一行代表一個關鍵詞)《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
總結
- 上一篇: 数据库自动定时备份
- 下一篇: mysql实现汉字转拼音