如果我们遇到需要对发布的文章进行敏感词审核,比如:
针孔摄象、信用卡提现、催情药水、小额贷款…
包含敏感词的话,就退回,否则就通过审核,应该怎么做呢?
备选方案:
下面就介绍一下DFA算法的使用。
DFA全称为:Deterministic Finite Automaton,即确定有穷自动机。
存储:一次性的把所有的敏感词存储到了多个map中,就是下图表示这种结构
敏感词:冰毒、大麻、大坏蛋
检索的过程:
public class SensitiveWordUtil { public static Map3.2 工具类的用法示例dictionaryMap = new HashMap<>(); public static void main(String[] args) { List list = new ArrayList<>(); list.add("色情"); list.add("迷情药"); list.add("嫖娼"); initMap(list); String content="我是一个好人,并不会搞色情,也不用迷情药,更不会嫖娼"; Map map = matchWords(content); System.out.println(map); } public static void initMap(Collection words) { if (words == null) { return ; } // map初始长度words.size(),整个字典库的入口字数(小于words.size(),因为不同的词可能会有相同的首字) Map map = new HashMap<>(words.size()); // 遍历过程中当前层次的数据 Map curMap = null; Iterator iterator = words.iterator(); while (iterator.hasNext()) { String word = iterator.next(); curMap = map; int len = word.length(); for (int i =0; i < len; i++) { // 遍历每个词的字 String key = String.valueOf(word.charAt(i)); // 当前字在当前层是否存在, 不存在则新建, 当前层数据指向下一个节点, 继续判断是否存在数据 Map wordMap = (Map ) curMap.get(key); if (wordMap == null) { // 每个节点存在两个数据: 下一个节点和isEnd(是否结束标志) wordMap = new HashMap<>(2); wordMap.put("isEnd", "0"); curMap.put(key, wordMap); } curMap = wordMap; // 当前的wordMap层作为下次遍历的curMap层 // 如果当前字是词的最后一个字,则将isEnd标志置1 if (i == len -1) { curMap.put("isEnd", "1"); } } } dictionaryMap = map; } private static int checkWord(String text, int beginIndex) { if (dictionaryMap == null) { throw new RuntimeException("字典不能为空"); } boolean isEnd = false; int wordLength = 0; Map curMap = dictionaryMap; int len = text.length(); // 从文本的第beginIndex开始匹配 for (int i = beginIndex; i < len; i++) { String key = String.valueOf(text.charAt(i)); // 获取当前key的下一个节点 curMap = (Map ) curMap.get(key); if (curMap == null) { break; } else { wordLength ++; if ("1".equals(curMap.get("isEnd"))) { isEnd = true; } } } if (!isEnd) { wordLength = 0; } return wordLength; } public static Map matchWords(String text) { Map wordMap = new HashMap<>(); int len = text.length(); for (int i = 0; i < len; i++) { int wordLength = checkWord(text, i); if (wordLength > 0) { String word = text.substring(i, i + wordLength); // 添加关键词匹配次数 if (wordMap.containsKey(word)) { wordMap.put(word, wordMap.get(word) + 1); } else { wordMap.put(word, 1); } i += wordLength - 1; } } return wordMap; } }
private boolean ScanSensitiveWord(String content) { boolean flag = true; //获取所有的敏感词 Listlist= ..... //初始化敏感词库 SensitiveWordUtil.initMap(list); //查看文章中是否包含敏感词 Map map = SensitiveWordUtil.matchWords(content); if(map.size() >0){ flag = false; } return flag; }
上就是过滤文本敏感词的写法,欢迎收藏,点赞。