关于java中敏感词检测的一些总结
生活随笔
收集整理的這篇文章主要介紹了
关于java中敏感词检测的一些总结
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
之前項目里客戶提出一個需求,需要對系統中使用文本轉化成語音發送的功能進行敏感詞檢測,禁止用戶提交有敏感詞的語音。通過查詢各方面資料,整理了大概幾種方案:
對于方案選擇,在網上參考了很多別人的代碼。最簡單的是方法2使用正則表達式,但是據說文本一長會有很大的效率問題。關于方法3DFA算法,由于在學校的時候算法課和編譯原理沒有認真聽講(慚愧= =||),直接就忽略這方法了,所以最后還是決定使用方法1。
其實方法1還是有很多可以改進的方法,后來又參考了這個帖子12樓中的方法,使用索引數組加關聯數組的方式,提高了檢索效率,甚至連分詞的步驟都省掉了。整個實現代碼如下。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | import org.apache.commons.lang.StringUtils; ?? import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; ?? import java.io.IOException; ?? import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; ?? ?? /** * User: eternity * Date: 2014/8/11 * Time: 16:17 * 敏感詞檢測類 * 敏感詞檢測初始化規則: * 將敏感詞從詞庫載入,按照2字、3字、4字、5字等字數各生成一個敏感詞哈希表。 * 在將這些哈希表組成一個數組banWordsList,數組下標表示該敏感詞表字數 * banWordsList[2] = {某馬:true,屏蔽:true,啦啦:true}; * banWordsList[3] = {某個馬:true,三個字:true,啦啦啦:true,小廣告:true}; * banWordsList[4] = {某個壞銀:true,四個字符:true,哈哈哈哈:true,就愛鳳姐:true}; * banWordsList[5] = {某個大法好:true,五個敏感字:true}; * 根據上面幾組組敏感詞,自動生成以下索引 * 生成規則為,索引名是敏感詞第一個字,值是一個int * 該int的規則為,該int轉換成二進制時,第i位為1表示上面4表存在長度為i的敏感詞,否則不存在長度為i的敏感詞(10000) * wordIndex = {二:0x04,三:0x08,四:0x10,五:0x20,某:0x3c,啦:0x0c,哈:0x10,小:0x08,就:0x10}; * * 檢查規則如下: * 1,逐字檢驗,是否該字在wordIndex索引表中。 * 2,如果不在表中,繼續檢驗 * 3,如果在表中,根據索引表該鍵的值,取此字以及此字后的若干字檢驗詳細表banWordsList[索引詞長]。 * * 檢驗例子 * 有一段如下文字,檢驗其是否包含敏感詞: “我就打小廣告,氣死版主” ——檢測“我” |-不在索引表 ——檢測“就” |-在索引表 |-“就”的索引值是0x10,表示有4字以“就”開頭的敏感詞 |-取“就”和后面的字共4個,組成“就打小廣” |-查4字敏感詞表,沒有這項,繼續 ——檢測“打” |-不在索引表 ——檢測“小” |-在索引表 |-索引值是0x08,表示有3字長度的敏感詞 |-取“小”和“小”后面的字,共3個字組成一個詞“小廣告” |-“小廣告”在3字敏感詞中,此帖包含敏感詞,禁止發布 */ public class BanWordsUtil { ????// public Logger logger = Logger.getLogger(this.getClass()); ????public static final int WORDS_MAX_LENGTH = 10; ????public static final String BAN_WORDS_LIB_FILE_NAME = "banWords.txt"; ?? ????//敏感詞列表 ????public static Map[] banWordsList = null; ?? ????//敏感詞索引 ????public static Map<String, Integer> wordIndex = new HashMap<String, Integer>(); ?? ????/* ????* 初始化敏感詞庫 ????*/ ????public static void initBanWordsList() throws IOException { ????????if (banWordsList == null) { ????????????banWordsList = new Map[WORDS_MAX_LENGTH]; ?? ????????????for (int i = 0; i < banWordsList.length; i++) { ????????????????banWordsList[i] = new HashMap<String, String>(); ????????????} ????????} ?? ????????//敏感詞詞庫所在目錄,這里為txt文本,一個敏感詞一行 ????????String path = BanWordsUtil.class.getClassLoader() ????????????????????????????????????????.getResource(BAN_WORDS_LIB_FILE_NAME) ????????????????????????????????????????.getPath(); ????????System.out.println(path); ?? ????????List<String> words = FileUtils.readLines(FileUtils.getFile(path)); ?? ????????for (String w : words) { ????????????if (StringUtils.isNotBlank(w)) { ????????????????//將敏感詞按長度存入map ????????????????banWordsList[w.length()].put(w.toLowerCase(), ""); ?? ????????????????Integer index = wordIndex.get(w.substring(0, 1)); ?? ????????????????//生成敏感詞索引,存入map ????????????????if (index == null) { ????????????????????index = 0; ????????????????} ?? ????????????????int x = (int) Math.pow(2, w.length()); ????????????????index = (index | x); ????????????????wordIndex.put(w.substring(0, 1), index); ????????????} ????????} ????} ?? ????/** ????* 檢索敏感詞 ????* @param content ????* @return ????*/ ????public static List<String> searchBanWords(String content) { ????????if (banWordsList == null) { ????????????try { ????????????????initBanWordsList(); ????????????} catch (IOException e) { ????????????????throw new RuntimeException(e); ????????????} ????????} ?? ????????List<String> result = new ArrayList<String>(); ?? ????????for (int i = 0; i < content.length(); i++) { ????????????Integer index = wordIndex.get(content.substring(i, i + 1)); ????????????int p = 0; ?? ????????????while ((index != null) && (index > 0)) { ????????????????p++; ????????????????index = index >> 1; ?? ????????????????String sub = ""; ?? ????????????????if ((i + p) < (content.length() - 1)) { ????????????????????sub = content.substring(i, i + p); ????????????????} else { ????????????????????sub = content.substring(i); ????????????????} ?? ????????????????if (((index % 2) == 1) && banWordsList[p].containsKey(sub)) { ????????????????????result.add(content.substring(i, i + p)); ?? ????????????????????// System.out.println("找到敏感詞:"+content.substring(i,i+p)); ????????????????} ????????????} ????????} ?? ????????return result; ????} ?? ????public static void main(String[] args) throws IOException { ????????String content = "含有敏感詞的測試語句。"; ????????BanWordsUtil.initBanWordsList(); ????????List<String> banWordList = BanWordsUtil.searchBanWords(content); ????????for(String s : banWordLis){ ?????????System.out.println("找到敏感詞:"+s); ????????} ????} } |
來自:http://my.oschina.net/u/1010578/blog/308904
總結
以上是生活随笔為你收集整理的关于java中敏感词检测的一些总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: boost::asio译文
- 下一篇: An Implementation of