SensitiveWord.java 5.5 KB

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