java实现敏感词过滤

来源:互联网 发布:速达软件数据库密码 编辑:程序博客网 时间:2024/04/28 23:07

java实现敏感词过滤

例如敏感词为:日本人、日本鬼子、毛泽东
构建一种树形结构如下图:

这样我们就将敏感词库构建成了一个类似于一颗一颗的树,我们判断一个词是否为敏感词时就大大减少了检索的匹配范围。
 比如我们要判断日本人,根据第一个字就可以确认需要检索的是哪棵树,然后再在这棵树中进行检索。

但是如何来判断一个敏感词已经结束了呢?利用标识位来判断。
所以实现这个功能,关键是如何来构建一棵棵这样的敏感词树。

   static Map sensitiveWordMap = null;   /**      * 读取敏感词库,将敏感词放入HashSet中,构建一个DFA算法模型:<br>      * 中 = {      *      isEnd = 0      *      国 = {<br>      *           isEnd = 1      *           人 = {isEnd = 0      *                民 = {isEnd = 1}      *                }      *           男  = {      *                  isEnd = 0      *                   人 = {      *                        isEnd = 1      *                       }      *               }      *           }      *      }      *  五 = {      *      isEnd = 0      *      星 = {      *          isEnd = 0      *          红 = {      *              isEnd = 0      *              旗 = {      *                   isEnd = 1      *                  }      *              }      *          }      *      }      * @date 2016年4月7日 17:08:06      * @param keyWordSet  敏感词库      * @version 1.0      */       private static void addSensitiveWordToHashMap(Set<String> keyWordSet) {          //初始化敏感词容器,减少扩容操作(100个敏感词可能构建了50颗树结构,可能用不了100size)        sensitiveWordMap = new HashMap(keyWordSet.size());           String key = null;         Map nowMap = null;          Map<String, String> newWordMap = 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,因为他不是最后一个                  newWordMap = new HashMap<String, String>();                  newWordMap.put("isEnd", "0");     //不是最后一个                      nowMap.put(keyChar, newWordMap);                      nowMap = newWordMap;                  }                  if(i == key.length()-1){                      nowMap.put("isEnd", "1");    //最后一个                }              }          }      }  
       /** * 获取文字中的敏感词 * @date 2016年4月7日 17:08:06  * @param txt 需要过滤的文本 * @param matchType 匹配规则 1:最小匹配规则,2:最大匹配规则 * @return * @version 1.0 */public static 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){    //存在,加入Set中sensitiveWordList.add(txt.substring(i, i+length));i = i + length - 1;    //减1的原因,是因为for会自增}}return sensitiveWordList;}
       /** * 检查文字中是否包含敏感字符,检查规则如下:<br> * @date 2016年4月7日 17:08:06 * @param txt 需要过滤的文本 * @param beginIndex * @param matchType * @return,如果存在,则返回敏感词字符的长度,不存在返回0 * @version 1.0 */public static int checkSensitiveWord(String txt, int beginIndex, int matchType){boolean flag = false;  //敏感词结束标识位:用于敏感词只有1位的情况int matchFlag = 0;     //匹配标识数默认为0char word = 0;Map nowMap = sensitiveWordMap;for(int i=beginIndex; i<txt.length(); i++){word = txt.charAt(i);nowMap = (Map) nowMap.get(word);//获取指定keyif(nowMap != null){//存在,则判断是否为最后一个matchFlag ++;  //找到相应key,匹配标识+1 if("1".equals(nowMap.get("isEnd"))){//如果为最后一个匹配规则,结束循环,返回匹配标识数flag = true;       //结束标志位为true   if(1 == matchType){//最小规则,直接返回,最大规则还需继续查找break;}}}else{//不存在,直接返回break;}}if(matchFlag < 2 || !flag){//长度必须大于等于1,为词 matchFlag = 0;}return matchFlag;}
       /** * 替换敏感字字符 * @date 2016年4月7日 17:08:06 * @param txt 需要过滤的文本 * @param matchType * @param replaceChar 替换字符,默认* * @version 1.0 */public static String replaceSensitiveWord(String txt, int matchType, String replaceChar){//if(StringUtils.isBlank(txt)) return null;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;}
       /** * 替换敏感字字符 * @date 2016年4月7日 17:08:06 * @param txt 需要过滤的文本 * @param matchType * @param replaceChar 替换字符,默认* * @version 1.0 */public static String replaceSensitiveWord(String txt, int matchType, String replaceChar){//if(StringUtils.isBlank(txt)) return null;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;}
       /** * Test * @param args */public static void main(String[] args) {Set<String> keyWordSet = new HashSet<String>();keyWordSet.add("中国人");keyWordSet.add("中国");keyWordSet.add("中国共产");//keyWordSet敏感词可以从数据库或文件读取addSensitiveWordToHashMap(keyWordSet);System.out.println("敏感词的数量:" + keyWordSet.size());//===================================================String str = "aaa中国人中国bbb";System.out.println("待检测语句字数:" + str.length());System.out.println(getSensitiveWord(str, 1));System.out.println(replaceSensitiveWord(str, 1, "*"));//aaa**人**bbbSystem.out.println("***********************************");System.out.println(getSensitiveWord(str, 2));System.out.println(replaceSensitiveWord(str, 2, "*"));//aaa*****bbb}

原文:http://blog.csdn.net/chenssy/article/details/26961957

0 0
原创粉丝点击