关于java中敏感词检测的一些总结
生活随笔
收集整理的這篇文章主要介紹了
关于java中敏感词检测的一些总结
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
之前項(xiàng)目里客戶提出一個(gè)需求,需要對(duì)系統(tǒng)中使用文本轉(zhuǎn)化成語(yǔ)音發(fā)送的功能進(jìn)行敏感詞檢測(cè),禁止用戶提交有敏感詞的語(yǔ)音。通過(guò)查詢各方面資料,整理了大概幾種方案:
對(duì)于方案選擇,在網(wǎng)上參考了很多別人的代碼。最簡(jiǎn)單的是方法2使用正則表達(dá)式,但是據(jù)說(shuō)文本一長(zhǎng)會(huì)有很大的效率問(wèn)題。關(guān)于方法3DFA算法,由于在學(xué)校的時(shí)候算法課和編譯原理沒(méi)有認(rèn)真聽講(慚愧= =||),直接就忽略這方法了,所以最后還是決定使用方法1。
其實(shí)方法1還是有很多可以改進(jìn)的方法,后來(lái)又參考了這個(gè)帖子12樓中的方法,使用索引數(shù)組加關(guān)聯(lián)數(shù)組的方式,提高了檢索效率,甚至連分詞的步驟都省掉了。整個(gè)實(shí)現(xiàn)代碼如下。
| 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 * 敏感詞檢測(cè)類 * 敏感詞檢測(cè)初始化規(guī)則: * 將敏感詞從詞庫(kù)載入,按照2字、3字、4字、5字等字?jǐn)?shù)各生成一個(gè)敏感詞哈希表。 * 在將這些哈希表組成一個(gè)數(shù)組banWordsList,數(shù)組下標(biāo)表示該敏感詞表字?jǐn)?shù) * banWordsList[2] = {某馬:true,屏蔽:true,啦啦:true}; * banWordsList[3] = {某個(gè)馬:true,三個(gè)字:true,啦啦啦:true,小廣告:true}; * banWordsList[4] = {某個(gè)壞銀:true,四個(gè)字符:true,哈哈哈哈:true,就愛鳳姐:true}; * banWordsList[5] = {某個(gè)大法好:true,五個(gè)敏感字:true}; * 根據(jù)上面幾組組敏感詞,自動(dòng)生成以下索引 * 生成規(guī)則為,索引名是敏感詞第一個(gè)字,值是一個(gè)int * 該int的規(guī)則為,該int轉(zhuǎn)換成二進(jìn)制時(shí),第i位為1表示上面4表存在長(zhǎng)度為i的敏感詞,否則不存在長(zhǎng)度為i的敏感詞(10000) * wordIndex = {二:0x04,三:0x08,四:0x10,五:0x20,某:0x3c,啦:0x0c,哈:0x10,小:0x08,就:0x10}; * * 檢查規(guī)則如下: * 1,逐字檢驗(yàn),是否該字在wordIndex索引表中。 * 2,如果不在表中,繼續(xù)檢驗(yàn) * 3,如果在表中,根據(jù)索引表該鍵的值,取此字以及此字后的若干字檢驗(yàn)詳細(xì)表banWordsList[索引詞長(zhǎng)]。 * * 檢驗(yàn)例子 * 有一段如下文字,檢驗(yàn)其是否包含敏感詞: “我就打小廣告,氣死版主” ——檢測(cè)“我” |-不在索引表 ——檢測(cè)“就” |-在索引表 |-“就”的索引值是0x10,表示有4字以“就”開頭的敏感詞 |-取“就”和后面的字共4個(gè),組成“就打小廣” |-查4字敏感詞表,沒(méi)有這項(xiàng),繼續(xù) ——檢測(cè)“打” |-不在索引表 ——檢測(cè)“小” |-在索引表 |-索引值是0x08,表示有3字長(zhǎng)度的敏感詞 |-取“小”和“小”后面的字,共3個(gè)字組成一個(gè)詞“小廣告” |-“小廣告”在3字敏感詞中,此帖包含敏感詞,禁止發(fā)布 */ 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>(); ?? ????/* ????* 初始化敏感詞庫(kù) ????*/ ????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>(); ????????????} ????????} ?? ????????//敏感詞詞庫(kù)所在目錄,這里為txt文本,一個(gè)敏感詞一行 ????????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)) { ????????????????//將敏感詞按長(zhǎng)度存入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 = "含有敏感詞的測(cè)試語(yǔ)句。"; ????????BanWordsUtil.initBanWordsList(); ????????List<String> banWordList = BanWordsUtil.searchBanWords(content); ????????for(String s : banWordLis){ ?????????System.out.println("找到敏感詞:"+s); ????????} ????} } |
來(lái)自:http://my.oschina.net/u/1010578/blog/308904
總結(jié)
以上是生活随笔為你收集整理的关于java中敏感词检测的一些总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: boost::asio译文
- 下一篇: An Implementation of