在一些评论文章中经常需要过滤敏感词,下面是过滤敏感词的步骤。
1.通过敏感词创建一个字典树的类
2.把所有敏感词放入字典树中
3.判断文章中是否有敏感词
1).创建一个字典树,字典树根节点不存数据,定义一个字典树的类,可以定义如下方法1.设置当前节点终结点,2.添加节点,3.获取下一个节点,4.判断是否为终点,
1 private class TrieNode { 2 /** 3 * true 关键词的终结 ; false 继续 4 */ 5 private boolean end = false; 6 /** 7 * key下一个字符,value是对应的节点 8 */ 9 private Map<Character, TrieNode> subNodes = new HashMap<>(); 10 /** 11 * 向指定位置添加节点树 12 */ 13 void addSubNode(Character key, TrieNode node) { 14 subNodes.put(key, node); 15 } 16 /** 17 * 获取下个节点 18 */ 19 TrieNode getSubNode(Character key) { 20 return subNodes.get(key); 21 } 22 boolean isKeywordEnd() { 23 return end; 24 } 25 void setKeywordEnd(boolean end) { 26 this.end = end; 27 } 28 public int getSubNodeCount() {//得到当前节点所有数量 暂时没用 29 return subNodes.size(); 30 } 31 }
/** * 根节点 */ private TrieNode rootNode = new TrieNode();
/** * 判断是否是一个符号 */ private boolean isSymbol(char c) { int ic = (int) c; // 0x2E80-0x9FFF 东亚文字范围 return !CharUtils.isAsciiAlphanumeric(c) && (ic < 0x2E80 || ic > 0x9FFF); }
2)把敏感词添加到字典树中
1 private void addWord(String lineTxt) { 2 TrieNode tempNode = rootNode; 3 // 循环每个字节 4 for (int i = 0; i < lineTxt.length(); ++i) { 5 Character c = lineTxt.charAt(i); 6 // 过滤空格 不是英文 不是东亚文字,则过滤 7 if (isSymbol(c)) { 8 continue; 9 } 10 TrieNode node = tempNode.getSubNode(c); 11 12 if (node == null) { // 没初始化 13 node = new TrieNode(); 14 tempNode.addSubNode(c, node); 15 } 16 17 tempNode = node; 18 19 if (i == lineTxt.length() - 1) { 20 // 关键词结束, 设置结束标志 21 tempNode.setKeywordEnd(true); 22 } 23 } 24 }
3)对文章内容进行敏感词过滤 1. rootNode 是根节点,2.begin是每一次比较敏感词开始的节点,3.position 是当前正在比较的位置
1 /** 2 * 过滤敏感词 3 */ 4 public String filter(String text) { 5 if (StringUtils.isBlank(text)) { 6 return text; 7 } 8 String replacement = "***";//用***代替敏感词 9 StringBuilder result = new StringBuilder(); //如果不是敏感词则存放在result中 10 11 TrieNode tempNode = rootNode; 12 int begin = 0; // 回滚数 13 int position = 0; // 当前比较的位置 14 15 while (position < text.length()) { 16 char c = text.charAt(position); 17 // 空格直接跳过 18 if (isSymbol(c)) { 19 if (tempNode == rootNode) { 20 result.append(c); 21 ++begin; 22 } 23 ++position; 24 continue; 25 } 26 27 tempNode = tempNode.getSubNode(c); 28 29 // 当前位置的匹配结束 30 if (tempNode == null) { 31 // 以begin开始的字符串不存在敏感词 32 result.append(text.charAt(begin)); 33 // 跳到下一个字符开始测试 34 position = begin + 1; 35 begin = position; 36 // 回到树初始节点 37 tempNode = rootNode; 38 } else if (tempNode.isKeywordEnd()) { 39 // 发现敏感词, 从begin到position的位置用replacement替换掉 40 result.append(replacement); 41 position = position + 1; 42 begin = position; 43 tempNode = rootNode; 44 } else { 45 ++position; 46 } 47 } 48 49 result.append(text.substring(begin)); 50 51 return result.toString(); 52 }
rootNode
最新评论