当前位置:   article > 正文

DFA算法实现 敏感词过滤_speech sensitive word filtering

speech sensitive word filtering

SensitiveWordInit

初始化敏感词库,将敏感词加入到HashMap中,构建DFA算法模型

  1. import java.io.BufferedReader;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.InputStreamReader;
  5. import java.util.HashMap;
  6. import java.util.HashSet;
  7. import java.util.Iterator;
  8. import java.util.Map;
  9. import java.util.Set;
  10. public class SensitiveWordInit {
  11. private String ENCODING = "GBK"; // 字符编码
  12. @SuppressWarnings("rawtypes")
  13. public HashMap sensitiveWordMap;
  14. public SensitiveWordInit() {
  15. super();
  16. }
  17. /**
  18. * @author chenming
  19. * @date 2014420日 下午2:28:32
  20. * @version 1.0
  21. */
  22. @SuppressWarnings("rawtypes")
  23. public Map initKeyWord() {
  24. try {
  25. // 读取敏感词库
  26. Set<String> keyWordSet = readSensitiveWordFile();
  27. // 将敏感词库加入到HashMap中
  28. addSensitiveWordToHashMap(keyWordSet);
  29. // spring获取application,然后application.setAttribute("sensitiveWordMap",sensitiveWordMap);
  30. } catch (Exception e) {
  31. e.printStackTrace();
  32. }
  33. return sensitiveWordMap;
  34. }
  35. /**
  36. * 读取敏感词库,将敏感词放入HashSet中,构建一个DFA算法模型:<br>
  37. *= { isEnd = 0= {<br>
  38. * isEnd = 1= {isEnd = 0= {isEnd = 1} } 男 = { isEnd = 0= { isEnd = 1 }
  39. * } } } 五 = { isEnd = 0= { isEnd = 0= { isEnd = 0= { isEnd = 1 } } } }
  40. *
  41. * @author chenming
  42. * @date 2014420日 下午3:04:20
  43. * @param keyWordSet 敏感词库
  44. * @version 1.0
  45. */
  46. @SuppressWarnings({ "rawtypes", "unchecked" })
  47. private void addSensitiveWordToHashMap(Set<String> keyWordSet) {
  48. sensitiveWordMap = new HashMap(keyWordSet.size()); // 初始化敏感词容器,减少扩容操作
  49. String key = null;
  50. Map nowMap = null;
  51. Map<String, String> newWorMap = null;
  52. // 迭代keyWordSet
  53. Iterator<String> iterator = keyWordSet.iterator();
  54. while (iterator.hasNext()) {
  55. key = iterator.next(); // 关键字
  56. nowMap = sensitiveWordMap;
  57. for (int i = 0; i < key.length(); i++) {
  58. char keyChar = key.charAt(i); // 转换成char型
  59. Object wordMap = nowMap.get(keyChar); // 获取
  60. if (wordMap != null) { // 如果存在该key,直接赋值
  61. nowMap = (Map) wordMap;
  62. } else { // 不存在则,则构建一个map,同时将isEnd设置为0,因为他不是最后一个
  63. newWorMap = new HashMap<String, String>();
  64. newWorMap.put("isEnd", "0"); // 不是最后一个
  65. nowMap.put(keyChar, newWorMap);
  66. nowMap = newWorMap;
  67. }
  68. if (i == key.length() - 1) {
  69. nowMap.put("isEnd", "1"); // 最后一个
  70. }
  71. }
  72. }
  73. }
  74. /**
  75. * 读取敏感词库中的内容,将内容添加到set集合中
  76. *
  77. * @author chenming
  78. * @date 2014420日 下午2:31:18
  79. * @return
  80. * @version 1.0
  81. * @throws Exception
  82. */
  83. @SuppressWarnings("resource")
  84. private Set<String> readSensitiveWordFile() throws Exception {
  85. Set<String> set = null;
  86. File file = new File("D:/TEST/SensitiveWord.txt"); // 读取文件
  87. InputStreamReader read = new InputStreamReader(new FileInputStream(file), ENCODING);
  88. try {
  89. if (file.isFile() && file.exists()) { // 文件流是否存在
  90. set = new HashSet<String>();
  91. BufferedReader bufferedReader = new BufferedReader(read);
  92. String txt = null;
  93. while ((txt = bufferedReader.readLine()) != null) { // 读取文件,将文件内容放入到set
  94. set.add(txt);
  95. }
  96. } else { // 不存在抛出异常信息
  97. throw new Exception("敏感词库文件不存在");
  98. }
  99. } catch (Exception e) {
  100. throw e;
  101. } finally {
  102. read.close(); // 关闭文件流
  103. }
  104. return set;
  105. }
  106. }

敏感词过滤

检查文字中是否包含敏感字符

  1. import java.util.HashSet;
  2. import java.util.Iterator;
  3. import java.util.Map;
  4. import java.util.Set;
  5. public class SensitivewordFilter {
  6. @SuppressWarnings("rawtypes")
  7. public Map sensitiveWordMap = null;
  8. public static int minMatchTYpe = 1; //最小匹配规则
  9. public static int maxMatchType = 2; //最大匹配规则
  10. /**
  11. * 构造函数,初始化敏感词库
  12. */
  13. public SensitivewordFilter(){
  14. sensitiveWordMap = new SensitiveWordInit().initKeyWord();
  15. }
  16. /**
  17. * 判断文字是否包含敏感字符
  18. * @author chenming
  19. * @date 2014420日 下午4:28:30
  20. * @param txt 文字
  21. * @param matchType 匹配规则&nbsp;1:最小匹配规则,2:最大匹配规则
  22. * @return 若包含返回true,否则返回false
  23. * @version 1.0
  24. */
  25. public boolean isContaintSensitiveWord(String txt,int matchType){
  26. boolean flag = false;
  27. for(int i = 0 ; i < txt.length() ; i++){
  28. int matchFlag = this.CheckSensitiveWord(txt, i, matchType); //判断是否包含敏感字符
  29. if(matchFlag > 0){ //大于0存在,返回true
  30. flag = true;
  31. }
  32. }
  33. return flag;
  34. }
  35. /**
  36. * 获取文字中的敏感词
  37. * @author chenming
  38. * @date 2014420日 下午5:10:52
  39. * @param txt 文字
  40. * @param matchType 匹配规则&nbsp;1:最小匹配规则,2:最大匹配规则
  41. * @return
  42. * @version 1.0
  43. */
  44. public Set<String> getSensitiveWord(String txt , int matchType){
  45. Set<String> sensitiveWordList = new HashSet<String>();
  46. for(int i = 0 ; i < txt.length() ; i++){
  47. int length = CheckSensitiveWord(txt, i, matchType); //判断是否包含敏感字符
  48. if(length > 0){ //存在,加入list中
  49. sensitiveWordList.add(txt.substring(i, i+length));
  50. i = i + length - 1; //1的原因,是因为for会自增
  51. }
  52. }
  53. return sensitiveWordList;
  54. }
  55. /**
  56. * 替换敏感字字符
  57. * @author chenming
  58. * @date 2014420日 下午5:12:07
  59. * @param txt
  60. * @param matchType
  61. * @param replaceChar 替换字符,默认*
  62. * @version 1.0
  63. */
  64. public String replaceSensitiveWord(String txt,int matchType,String replaceChar){
  65. String resultTxt = txt;
  66. Set<String> set = getSensitiveWord(txt, matchType); //获取所有的敏感词
  67. Iterator<String> iterator = set.iterator();
  68. String word = null;
  69. String replaceString = null;
  70. while (iterator.hasNext()) {
  71. word = iterator.next();
  72. replaceString = getReplaceChars(replaceChar, word.length());
  73. resultTxt = resultTxt.replaceAll(word, replaceString);
  74. }
  75. return resultTxt;
  76. }
  77. /**
  78. * 获取替换字符串
  79. * @author chenming
  80. * @date 2014420日 下午5:21:19
  81. * @param replaceChar
  82. * @param length
  83. * @return
  84. * @version 1.0
  85. */
  86. private String getReplaceChars(String replaceChar,int length){
  87. String resultReplace = replaceChar;
  88. for(int i = 1 ; i < length ; i++){
  89. resultReplace += replaceChar;
  90. }
  91. return resultReplace;
  92. }
  93. /**
  94. * 检查文字中是否包含敏感字符,检查规则如下:<br>
  95. * @author chenming
  96. * @date 2014420日 下午4:31:03
  97. * @param txt
  98. * @param beginIndex
  99. * @param matchType
  100. * @return,如果存在,则返回敏感词字符的长度,不存在返回0
  101. * @version 1.0
  102. */
  103. @SuppressWarnings({ "rawtypes"})
  104. public int CheckSensitiveWord(String txt,int beginIndex,int matchType){
  105. boolean flag = false; //敏感词结束标识位:用于敏感词只有1位的情况
  106. int matchFlag = 0; //匹配标识数默认为0
  107. char word = 0;
  108. Map nowMap = sensitiveWordMap;
  109. for(int i = beginIndex; i < txt.length() ; i++){
  110. word = txt.charAt(i);
  111. nowMap = (Map) nowMap.get(word); //获取指定key
  112. if(nowMap != null){ //存在,则判断是否为最后一个
  113. matchFlag++; //找到相应key,匹配标识+1
  114. if("1".equals(nowMap.get("isEnd"))){ //如果为最后一个匹配规则,结束循环,返回匹配标识数
  115. flag = true; //结束标志位为true
  116. if(SensitivewordFilter.minMatchTYpe == matchType){ //最小规则,直接返回,最大规则还需继续查找
  117. break;
  118. }
  119. }
  120. }
  121. else{ //不存在,直接返回
  122. break;
  123. }
  124. }
  125. if(matchFlag < 2 || !flag){ //长度必须大于等于1,为词
  126. matchFlag = 0;
  127. }
  128. return matchFlag;
  129. }
  130. public static void main(String[] args) {
  131. SensitivewordFilter filter = new SensitivewordFilter();
  132. System.err.println(filter.sensitiveWordMap);
  133. System.out.println("敏感词的数量:" + filter.sensitiveWordMap.size());
  134. String string = "太多的伤感情怀也许只局限于饲养基地 荧幕中的情节,主人公尝试着去用某种方式渐渐的很潇洒地释自杀指南怀那些自己经历的伤感。"
  135. + "然后法轮功 我们的扮演的角色就是跟随着主人公的喜红客联盟 怒哀乐而过于牵强的把自己的情感也附加于银幕情节中,然后感动就流泪,"
  136. + "难过就躺在某一个人的怀里尽情的阐述心扉或者手机卡复制器一个人一杯红酒一部电影在夜三级片 深人静的晚上,关上电话静静的发呆着。";
  137. System.out.println("待检测语句字数:" + string.length());
  138. long beginTime = System.currentTimeMillis();
  139. Set<String> set = filter.getSensitiveWord(string, 1);
  140. long endTime = System.currentTimeMillis();
  141. System.out.println("语句中包含敏感词的个数为:" + set.size() + "。包含:" + set);
  142. System.out.println("总共消耗时间为:" + (endTime - beginTime));
  143. }
  144. }

DFA实现模型

通过 CheckSensitiveWord 比较, 获取值得长度, 更具原始的位置, 可以定位值的坐标

转载与网络

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/153854
推荐阅读
相关标签
  

闽ICP备14008679号