Java使用DFA算法實現(xiàn)過濾多家公司自定義敏感字功能詳解
本文實例講述了Java使用DFA算法實現(xiàn)過濾多家公司自定義敏感字功能。分享給大家供大家參考,具體如下:
背景
因為最近有通訊有個需求,說需要讓多家客戶公司可以自定義敏感詞過濾掉他們自定義的規(guī)則,選擇了DFA算法來做,不過和以前傳統(tǒng)了DFA寫法不太一樣了
模式圖
直接上代碼
public class KeywordFilter { // private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public static Map<String, HashMap> currentMap = new ConcurrentHashMap<String, HashMap>(); public static Map nowhash = null; public static Object wordMap;// map子節(jié)點 // 不建立對象 private KeywordFilter() { } private static String getKey(int companyId) { return "companyId" + companyId; } /* * <p>說明:清掃內(nèi)容</p> * * @author:姚旭民 * * @data:2017-8-22 上午10:13:11 */ public static void clear() { try { currentMap.clear(); } catch (Exception e) { e.printStackTrace(); } finally { } } /* * <p>說明:各個渠道的過濾字符</p> * * @author:姚旭民 * * @data:2017-8-20 下午2:55:06 */ public static void saveKeywords(int companyId, List<String> keywords) { try { Map tempAllMap = currentMap; String key = getKey(companyId); int l = keywords.size(); int il; Map tempMap; for (int i = 0; i < l; i++) { String key2 = keywords.get(i).trim();// 去掉空白 nowhash = currentMap; il = key2.length(); for (int j = 0; j < il; j++) { char word = key2.charAt(j); tempMap = (Map) nowhash.get(word); wordMap = nowhash.get(word); if (wordMap != null) {// 檢查數(shù)據(jù) if (!tempMap.containsKey(key)) { nowhash.put(key, 0); } nowhash = (HashMap) wordMap; } else { HashMap<String, String> newWordHash = new HashMap<String, String>(); newWordHash.put(key, "0"); nowhash.put(word, newWordHash); nowhash = newWordHash; } if (j == il - 1) { nowhash.put(key, "1"); } } } } catch (Exception e) { e.printStackTrace(); } finally { nowhash = null; wordMap = null; } } /* * <p>說明:替換掉對應的渠道規(guī)定掉敏感字</p> * * @author:姚旭民 * * @data:2017-8-20 上午11:41:47 */ public static List<String> repword(int companyId, String txt) { Map tempMap = currentMap; List<String> result = new ArrayList<String>(); String key = getKey(companyId); nowhash = currentMap; int l = txt.length(); char word; String keywordStr = ""; String keyStatu; StringBuilder keyword = new StringBuilder();// 敏感字 for (int i = 0; i < l; i++) { word = txt.charAt(i); wordMap = nowhash.get(word); if (wordMap != null) {// 找到類似敏感字的字體,開始查詢 keyword.append(word); Object te = nowhash = (HashMap) wordMap; // 遍歷到這一步,就符合完整的關鍵字模板 if (nowhash.get(key) != null && nowhash.get(key).toString().equals("1")) {// 確定是敏感字,開始替換 if (i < l - 1 && nowhash.get(txt.charAt(i + 1)) != null) {// 優(yōu)先過濾長敏感詞,去掉就檳城了優(yōu)先過濾段敏感詞 continue; } txt = txt.replaceAll(keyword.toString(), "*"); nowhash = currentMap; keywordStr += keyword.toString() + ","; i = i - keyword.length() + 1; l = txt.length();// 重新獲取字符長度 keyword.delete(0, keyword.length());// 清空數(shù)據(jù) } } else {// 這個字不是敏感字,直接排除 nowhash = currentMap; keyword.delete(0, keyword.length());// 清空數(shù)據(jù) continue; } } // 清除內(nèi)存指向 nowhash = null; wordMap = null; result.add(txt); result.add(keywordStr.length() - 1 > 0 ? keywordStr.substring(0, keywordStr.length() - 1) : keywordStr); return result; } /* * <p>說明:檢查是否存在敏感字</p> * * @author:姚旭民 * * @data:2017-8-20 下午3:00:06 專門設計成私有的,如果沒有理由,別改動他 */ private static int checkKeyWords(String txt, int companyId, int begin) { int result = 0; String key = getKey(companyId); try { nowhash = currentMap; int l = txt.length(); char word = 0; for (int i = begin; i < l; i++) { word = txt.charAt(i); wordMap = nowhash.get(word); if (wordMap != null) { result++; nowhash = (HashMap) wordMap; if (((String) nowhash.get(key)).equals("1")) { nowhash = null; wordMap = null; return result; } } else { result = 0; break; } } } catch (Exception e) { e.printStackTrace(); } finally { nowhash = null; wordMap = null; return result; } } /* * <p>說明:返回檢查的文本中包含的敏感字</p> * * @author:姚旭民 * * @data:2017-8-20 下午3:32:53 */ public static String getTxtKeyWords(String txt, int companyId) { String result = null; StringBuilder temp = new StringBuilder(); String key; int l = txt.length(); for (int i = 0; i < l;) { int len = checkKeyWords(txt, companyId, i); if (len > 0) { key = (txt.substring(i, i + len));// 挑選出來的關鍵字 temp.append(key + ","); txt = txt.replaceAll(key, "");// 挑選出來的關鍵字替換成空白,加快挑選速度 l = txt.length(); } else { i++; } } if (temp.length() > 0) { result = temp.substring(0, temp.length() - 1); } return result; } /* * <p>說明:判斷文中是否包含渠道規(guī)定的敏感字</p> * * @author:姚旭民 * * @data:2017-8-20 下午3:33:19 */ public boolean isKeyWords(String txt, int companyId) { for (int i = 0; i < txt.length(); i++) { int len = checkKeyWords(txt, companyId, i); if (len > 0) { return true; } } return false; } public static void main(String[] arg) { List<String> keywords = new ArrayList<String>(); keywords.add("傻×"); keywords.add("漢奸"); keywords.add("草"); keywords.add("草泥馬"); KeywordFilter.saveKeywords(1, keywords); String txt = "是傻×漢奸傻A傻B傻C傻D漢奸傻×草泥馬"; List<String> list = repword(1, txt); System.out.println("文中包含的敏感字為:" + list.get(1)); System.out.println("原文:" + txt); System.out.println("敏感字過濾后:" + list.get(0)); } }
更多關于java算法相關內(nèi)容感興趣的讀者可查看本站專題:《Java數(shù)據(jù)結構與算法教程》、《Java字符與字符串操作技巧總結》、《Java操作DOM節(jié)點技巧總結》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設計有所幫助。
相關文章
淺談Java中Lock和Synchronized的區(qū)別
這篇文章主要介紹了Java中Lock和Synchronized的區(qū)別,Lock和Synchronized都是java中去用來解決線程安全問題的一個工具,但是具體有什么區(qū)別呢?下面我們一起進入文章了解具體詳細內(nèi)容吧,需要的朋友可以參考一下2022-04-04SpringBoot無法訪問/static下靜態(tài)資源的解決
這篇文章主要介紹了SpringBoot無法訪問/static下靜態(tài)資源的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09Spring security實現(xiàn)記住我下次自動登錄功能過程詳解
這篇文章主要介紹了Spring security實現(xiàn)記住我下次自動登錄功能過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-03-03Java根據(jù)URL下載文件到本地的2種方式(大型文件與小型文件)
這篇文章主要給大家介紹了關于Java根據(jù)URL下載文件到本地的2種方式,分別是大型文件與小型文件,避免內(nèi)存溢出OOM,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-01-01jdbc連SQL?server顯示1433端口連接失敗圖文解決方法
這篇文章主要給大家介紹了關于jdbc連SQL?server顯示1433端口連接失敗的圖文解決方法,文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考借鑒價值,需要的朋友可以參考下2024-06-06詳解Spring Data JPA系列之投影(Projection)的用法
本篇文章主要介紹了詳解Spring Data JPA系列之投影(Projection)的用法,具有一定的參考價值,有興趣的可以了解一下2017-07-07