Java 敏感词替换-dfa算法,效率高

实现的步骤:1.用一个方法来读取敏感词放入一个List集合

                      2.写一个敏感词库方法读取集合中的敏感词,然后生成树形结构,

                      3.写一个查询传入字符串查询其中的敏感词的方法,找到字符串中的敏感词

                      4.替换敏感词

 

写一个工具类,包含读取敏感词,生成敏感词库,检查字符串中的敏感词几个方法

 

 

package com.utils.dfa;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.*;

/**
 * @Description: 初始化敏感词库,将敏感词加入到HashMap中,构建DFA算法模型
 * @Project:test
 * @Author : SPF
 * @version 1.0
 */
public class SensitiveWordInit {
   private String ENCODING = "UTF-8";    //字符编码
   @SuppressWarnings("rawtypes")
   public static HashMap sensitiveWordMap;

   public SensitiveWordInit(){
      super();
   }

   /**
    * 初始化词库
    * @param datas 敏感词集合
    * @return
    */
   public static HashMap init(List<String> datas) {
      addSensitiveWord(datas);
      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
    *                  }
    *              }
    *         }
    *      }
    *   {退={党={isEnd=1}, isEnd=0}, 老={isEnd=0, 虎={机={上={分={器={isEnd=1}, isEnd=0}, isEnd=0}, isEnd=1}, isEnd=0}}
    */
   private static void addSensitiveWord(List<String> datas) {
      sensitiveWordMap = new HashMap(datas.size());
      Iterator<String> iterator = datas.iterator();
      Map<String, Object> now = null;
      Map now2 = null;
      while (iterator.hasNext()) {
         now2 = sensitiveWordMap;
         String word = iterator.next().trim(); //敏感词
         for (int i = 0; i < word.length(); i++) {
            char key_word = word.charAt(i);
            Object obj = now2.get(key_word);
            if (obj != null) { //存在
               now2 = (Map) obj;
            } else { //不存在
               now =  new HashMap<String, Object>();
               now.put("isEnd","0");
               now2.put(key_word, now);
               now2 = now;
            }
            if (i == word.length() - 1) {
               now2.put("isEnd","1");
            }
         }
      }
   }

   /**
    * 获取内容中的敏感词
    * @param text 内容
    * @param matchType 匹配规则 1=不最佳匹配,2=最佳匹配
    * @return
    */
   public static List<String> getSensitiveWord(String text, int matchType) {
      List<String> words = new ArrayList<String>();
      Map now = sensitiveWordMap;
      int count = 0;  //初始化敏感词长度
      int start = 0; //标志敏感词开始的下标
      for (int i = 0; i < text.length(); i++) {
         char key = text.charAt(i);
         now = (Map) now.get(key);
         if (now != null) { //存在
            count++;
            if (count ==1) {
               start = i;
            }
            if ("1".equals(now.get("isEnd"))) { //敏感词结束
               now = sensitiveWordMap; //重新获取敏感词库
               words.add(text.substring(start, start + count)); //取出敏感词,添加到集合
               count = 0; //初始化敏感词长度
            }
         } else { //不存在
            now = sensitiveWordMap;//重新获取敏感词库
            if (count == 1 && matchType == 1) { //不最佳匹配
               count = 0;
            } else if (count == 1 && matchType == 2) { //最佳匹配
               words.add(text.substring(start, start + count));
               count = 0;
            }
         }
      }
      return words;
   }

   /**
    * 从文件中读取敏感词库中的内容,将内容添加到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("F:\\SPF\\项目\\敏感词过滤\\敏感词汇\\敏感词库\\敏感词2\\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;
   }
}

 

 

写个一个提供给接口的替换铭感词的方法类

 

 

package com.utils.dfa;

import java.util.*;

/**
 * @Description: 敏感词过滤
 * @Project:test
 * @version 1.0
 */
public class SensitivewordFilter {
   @SuppressWarnings("rawtypes")
   private static Map sensitiveWordMap = null;
   public static int minMatchTYpe = 1;      //最小匹配规则
   public static int maxMatchType = 2;      //最大匹配规则

   private static void initSensitiveWord(List<String> datas) {
      sensitiveWordMap = SensitiveWordInit.init(datas);
   }

   /**
    * 替换敏感字字符
    * @author chenming
    * @date 2014年4月20日 下午5:12:07
    * @param txt
    * @param matchType
    * @param replaceChar 替换字符,默认*
    * @version 1.0
    */
   public static String replaceSensitiveWord(List<String> datas, String txt,int matchType,String replaceChar){
      if (sensitiveWordMap == null) {
         initSensitiveWord(datas);
      }
      String resultTxt = txt;
      List<String> set = SensitiveWordInit.getSensitiveWord(txt, matchType);     //获取所有的敏感词
      System.out.println(set);
      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 static String getReplaceChars(String replaceChar,int length){
      String resultReplace = replaceChar;
      if (length > 6) {
         length = 6;
      }
      for(int i = 1 ; i < length ; i++){
         resultReplace += replaceChar;
      }
      return resultReplace;
   }


   /**
    * 添加敏感词
    * @param str
    */
   private static boolean addSensitiveWord(String str) {
      if (sensitiveWordMap == null) {
         return false;
      }
      Map nowMap = null;
      Map<String, String> newWorMap = null;
         nowMap = sensitiveWordMap;
         for(int i = 0 ; i < str.length() ; i++){
            char keyChar = str.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 == str.length() - 1){
               nowMap.put("isEnd", "1");    //最后一个
            }
         }
         return  true;
   }

   public static void main(String[] args) {
      List<String> datas = new ArrayList<String>();
        datas.add("滚");datas.add("卧槽");datas.add("你麻痹");datas.add("去你麻痹");
        datas.add("卧去");datas.add("卧去U");
        initSensitiveWord(datas);
        addSensitiveWord("MDZZQUN");
        String str = "卧去,尼玛,卧槽牛黄弩机滚,你麻痹你能见MDZZQUN到健康去你麻痹";
      String rep =  replaceSensitiveWord(datas,str,1,"*");
      System.out.println(rep);
   }

转载: https://blog.csdn.net/qq_32331997/article/details/73732493 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值