javaはDFAアルゴリズムを利用して、敏感語フィルタ機能を実現します。


前言
敏感語のフィルタリングは皆さんに説明しなくてもいいですよね?はっきり言ってください。プロジェクトに何かの文字を入力する時、検査ができます。
測定します。多くの項目には敏感語管理モジュールがあります。敏感語管理モジュールには敏感語を入れて、加えた敏感語によってフィルタリングします。
内容中の敏感語を入力して対応する処理を行います。ヒントを与えるか、ハイライトを表示するか、あるいは直接他の文字や記号に置き換えます。
敏感語のフィルタリングのやり方はいろいろあります。私が今理解していることを簡単に説明します。
①データベースの中の敏感語を調べて、各敏感語を循環して、入力したテキストの中で最初から最後まで検索して、この敏感語があるかどうかを確認します。あるなら、それを実行します。
このようなやり方ははっきり言えば、一つの処理を見つけます。
特典:ソフィア。javaコードで実現するのは基本的に難しくないです。
短所:この効率は私の心の中を十万匹の草泥馬に走らせたことがあります。それに合うのは卵の痛みがありますか?もし英語だったら、あなたは英語のような無口なことを発見します。
aは敏感語です。英語の文書なら、妹は何回敏感語を処理しますか?誰か教えてくれませんか?
②伝説のDFAアルゴリズム(貧乏自动机があります)も、私が皆さんに共有したいと思っています。やはり感覚は通用します。アルゴリズムの原理は自分でネットで調べてもらいたいです。
資料はここで詳しく説明しません。
長所:少なくとも上記のsbより効率が高いです。
短所:アルゴリズムを勉強したことがあるのは難しくないはずです。アルゴリズムを習ったことがないので、使うのも難しくないです。つまり、理解するのは少しggが痛いです。整合効率も高くないし、メモリを消費します。
敏感語が多ければ多いほど、メモリの占有量が大きくなります。
③三つ目はここで特に説明します。それは自分でアルゴリズムを書いてください。あるいは既存のアルゴリズムをもとに最適化します。これも追求の最高の境地の一つです。
伝説のDFAアルゴリズムはどうやって実現されますか?
第一歩:敏感語彙初期化(敏感語用DFAアルゴリズムの原理を敏感詞庫に入れ、敏感辞書はHashMapで保存する)、コードは以下の通りである。

package com.cfwx.rox.web.sysmgr.util;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.cfwx.rox.web.common.model.entity.SensitiveWord;

/**
 *        
 * 
 * @author AlanLee
 *
 */
public class SensitiveWordInit
{
  /**
   *     
   */
  public HashMap sensitiveWordMap;

  /**
   *       
   * 
   * @return
   */
  public Map initKeyWord(List<SensitiveWord> sensitiveWords)
  {
    try
    {
      //                   Set   
      Set<String> keyWordSet = new HashSet<String>();
      for (SensitiveWord s : sensitiveWords)
      {
        keyWordSet.add(s.getContent().trim());
      }
      //         HashMap 
      addSensitiveWordToHashMap(keyWordSet);
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    return sensitiveWordMap;
  }

  /**
   *       
   * 
   * @param keyWordSet
   */
  @SuppressWarnings("rawtypes")
  private void addSensitiveWordToHashMap(Set<String> keyWordSet)
  {
    //    HashMap          
    sensitiveWordMap = new HashMap(keyWordSet.size());
    //    
    String key = null;
    //                  
    Map nowMap = null;
    //           
    Map<String, String> newWorMap = null;
    //                
    Iterator<String> iterator = keyWordSet.iterator();
    while (iterator.hasNext())
    {
      key = iterator.next();
      //       ,HashMap               ,   nowMap     ,sensitiveWordMap        
      nowMap = sensitiveWordMap;
      for (int i = 0; i < key.length(); i++)
      {
        //          ,        HashMap   Key  
        char keyChar = key.charAt(i);

        //                
        Object wordMap = nowMap.get(keyChar);
        if (wordMap != null)
        {
          nowMap = (Map) wordMap;
        }
        else
        {
          newWorMap = new HashMap<String, String>();
          newWorMap.put("isEnd", "0");
          nowMap.put(keyChar, newWorMap);
          nowMap = newWorMap;
        }

        //                 ,       
        if (i == key.length() - 1)
        {
          nowMap.put("isEnd", "1");
        }
        System.out.println("        :"+sensitiveWordMap);
      }
      System.out.println("        :" + sensitiveWordMap);
    }
  }
}
第二ステップ:敏感語フィルタの種類を書いて、中に自分の必要な方法を書いてもいいです。コードは以下の通りです。

package com.cfwx.rox.web.sysmgr.util;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 *         
 * 
 * @author AlanLee
 *
 */
public class SensitivewordEngine
{
  /**
   *     
   */
  public static Map sensitiveWordMap = null;

  /**
   *         
   */
  public static int minMatchTYpe = 1;

  /**
   *        
   */
  public static int maxMatchType = 2;

  /**
   *          
   * 
   * @return
   */
  public static int getWordSize()
  {
    if (SensitivewordEngine.sensitiveWordMap == null)
    {
      return 0;
    }
    return SensitivewordEngine.sensitiveWordMap.size();
  }

  /**
   *        
   * 
   * @param txt
   * @param matchType
   * @return
   */
  public static boolean isContaintSensitiveWord(String txt, int matchType)
  {
    boolean flag = false;
    for (int i = 0; i < txt.length(); i++)
    {
      int matchFlag = checkSensitiveWord(txt, i, matchType);
      if (matchFlag > 0)
      {
        flag = true;
      }
    }
    return flag;
  }

  /**
   *        
   * 
   * @param txt
   * @param matchType
   * @return      
   */
  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)
      {
        //               
        sensitiveWordList.add(txt.substring(i, i + length));
        i = i + length - 1;
      }
    }

    return sensitiveWordList;
  }

  /**
   *      
   * 
   * @param txt
   * @param matchType
   * @param replaceChar
   * @return
   */
  public static 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;
  }

  /**
   *        
   * 
   * @param replaceChar
   * @param length
   * @return
   */
  private static String getReplaceChars(String replaceChar, int length)
  {
    String resultReplace = replaceChar;
    for (int i = 1; i < length; i++)
    {
      resultReplace += replaceChar;
    }

    return resultReplace;
  }

  /**
   *        
   * 
   * @param txt
   * @param beginIndex
   * @param matchType
   * @return
   */
  public static int checkSensitiveWord(String txt, int beginIndex, int matchType)
  {
    boolean flag = false;
    //        
    int matchFlag = 0;
    char word = 0;
    Map nowMap = SensitivewordEngine.sensitiveWordMap;
    for (int i = beginIndex; i < txt.length(); i++)
    {
      word = txt.charAt(i);
      //               
      nowMap = (Map) nowMap.get(word);
      if (nowMap != null)
      {
        matchFlag++;
        //             ,               
        if ("1".equals(nowMap.get("isEnd")))
        {
          flag = true;
          //       ,           ,      
          if (SensitivewordEngine.minMatchTYpe == matchType)
          {
            break;
          }
        }
      }
      else
      {
        break;
      }
    }
    if (!flag)
    {
      matchFlag = 0;
    }
    return matchFlag;
  }

}
第三ステップ:すべての準備ができました。もちろんデータベースの中の敏感語を調べて、フィルタリングを始めました。コードは以下の通りです。

@SuppressWarnings("rawtypes")
  @Override
  public Set<String> sensitiveWordFiltering(String text)
  {
    //          
    SensitiveWordInit sensitiveWordInit = new SensitiveWordInit();
    //               (       Dao ,    service     )
    List<SensitiveWord> sensitiveWords = sensitiveWordDao.getSensitiveWordListAll();
    //       
    Map sensitiveWordMap = sensitiveWordInit.initKeyWord(sensitiveWords);
    //   SensitivewordEngine       
    SensitivewordEngine.sensitiveWordMap = sensitiveWordMap;
    //         ,  2         
    Set<String> set = SensitivewordEngine.getSensitiveWord(text, 2);
    return set;
  }
最後のステップ:Controller層に方法を書いてフロントエンドに要求し、フロントエンドは必要なデータを取得し、対応する処理を行います。コードは以下の通りです。

/**
   *      
   * 
   * @param text
   * @return
   */
  @RequestMapping(value = "/word/filter")
  @ResponseBody
  public RespVo sensitiveWordFiltering(String text)
  {
    RespVo respVo = new RespVo();
    try
    {
      Set<String> set = sensitiveWordService.sensitiveWordFiltering(text);
      respVo.setResult(set);
    }
    catch (Exception e)
    {
      throw new RoxException("       ,       ");
    }

    return respVo;
  }
締め括りをつける
以上がこの文章の内容です。コードに多くの注釈が書いてあります。自分の頭を動かしてよく理解してください。この文章の内容が皆さんの学習や仕事に一定の助けを与えてくれることを願っています。質問があれば、メッセージを残して交流してください。ありがとうございます。