项目目录结构如下:

其中resources资源目录中:

stopwd.txt :停顿词,匹配时间直接过滤。

wd.txt:敏感词库。

1、WordFilter敏感词过滤类:

 package com.skyer.sensitivewdfilter;

 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;

 /**
  * 思路: 创建一个FilterSet,枚举了0~65535的所有char是否是某个敏感词开头的状态
  *
  * 判断是否是 敏感词开头 | | 是 不是 获取头节点 OK--下一个字 然后逐级遍历,DFA算法
  */
 public class WordFilter {

     private static final FilterSet set = new FilterSet(); // 存储首字
     private static final Map<Integer, WordNode> nodes = new HashMap<Integer, WordNode>(1024, 1); // 存储节点
     private static final Set<Integer> stopwdSet = new HashSet<Integer>(); // 停顿词
     private static final char SIGN = '*'; // 敏感词过滤替换

     static {
         try {
             long a = System.nanoTime();
             init();
             a = System.nanoTime() - a;
             System.out.println("加载时间 : " + a + "ns");
             System.out.println("加载时间 : " + a / 1000000 + "ms");
         } catch (Exception e) {
             throw new RuntimeException("初始化过滤器失败");
         }
     }

     private static void init() {
         // 获取敏感词
         addSensitiveWord(readWordFromFile("wd.txt"));
         addStopWord(readWordFromFile("stopwd.txt"));
     }

     /**
      * 增加敏感词
      */
     private static List<String> readWordFromFile(String path) {
         List<String> words;
         BufferedReader br = null;
         try {
             br = new BufferedReader(new InputStreamReader(WordFilter.class.getClassLoader().getResourceAsStream(path)));
             words = new ArrayList<String>(1200);
             for (String buf = ""; (buf = br.readLine()) != null;) {
                 if (buf == null || buf.trim().equals(""))
                     continue;
                 words.add(buf);
             }
         } catch (Exception e) {
             throw new RuntimeException(e);
         } finally {
             try {
                 if (br != null)
                     br.close();
             } catch (IOException e) {
             }
         }
         return words;
     }

     /**
      * 增加停顿词
      */
     private static void addStopWord(final List<String> words) {
         if (words != null && words.size() > 0) {
             char[] chs;
             for (String curr : words) {
                 chs = curr.toCharArray();
                 for (char c : chs) {
                     stopwdSet.add(charConvert(c));
                 }
             }
         }
     }

     /**
      * 添加DFA节点
      */
     private static void addSensitiveWord(final List<String> words) {
         if (words != null && words.size() > 0) {
             char[] chs;
             int fchar;
             int lastIndex;
             WordNode fnode; // 首字母节点
             for (String curr : words) {
                 chs = curr.toCharArray();
                 fchar = charConvert(chs[0]);
                 if (!set.contains(fchar)) {// 没有首字定义
                     set.add(fchar);// 首字标志位 可重复add
                     fnode = new WordNode(fchar, chs.length == 1);
                     nodes.put(fchar, fnode);
                 } else {
                     fnode = nodes.get(fchar);
                     if (!fnode.isLast() && chs.length == 1)
                         fnode.setLast(true);
                 }
                 lastIndex = chs.length - 1;
                 for (int i = 1; i < chs.length; i++) {
                     fnode = fnode.addIfNoExist(charConvert(chs[i]), i == lastIndex);
                 }
             }
         }
     }

     /**
      * 过滤判断 将敏感词转化为成屏蔽词
      */
     public static final String doFilter(final String src) {
         char[] chs = src.toCharArray();
         int length = chs.length;
         int currc;
         int k;
         WordNode node;
         for (int i = 0; i < length; i++) {
             currc = charConvert(chs[i]);
             if (!set.contains(currc)) {
                 continue;
             }
             node = nodes.get(currc);
             if (node == null)
                 continue;
             boolean couldMark = false;
             int markNum = -1;
             if (node.isLast()) {
                 couldMark = true;
                 markNum = 0;
             }
             k = i;
             for (; ++k < length;) {
                 int temp = charConvert(chs[k]);
                 if (stopwdSet.contains(temp))
                     continue;
                 node = node.querySub(temp);
                 if (node == null)
                     break;
                 if (node.isLast()) {
                     couldMark = true;
                     markNum = k - i;
                 }
             }
             if (couldMark) {
                 for (k = 0; k <= markNum; k++) {
                     chs[k + i] = SIGN;
                 }
                 i = i + markNum;
             }
         }

         return new String(chs);
     }

     /**
      * 是否包含敏感词
      */
     public static final boolean isContains(final String src) {
         char[] chs = src.toCharArray();
         int length = chs.length;
         int currc;
         int k;
         WordNode node;
         for (int i = 0; i < length; i++) {
             currc = charConvert(chs[i]);
             if (!set.contains(currc)) {
                 continue;
             }
             node = nodes.get(currc);
             if (node == null)
                 continue;
             boolean couldMark = false;
             if (node.isLast()) {
                 couldMark = true;
             }
             k = i;
             for (; ++k < length;) {
                 int temp = charConvert(chs[k]);
                 if (stopwdSet.contains(temp))
                     continue;
                 node = node.querySub(temp);
                 if (node == null)
                     break;
                 if (node.isLast()) {
                     couldMark = true;
                 }
             }
             if (couldMark) {
                 return true;
             }
         }

         return false;
     }

     /**
      * 大写转化为小写 全角转化为半角
      */
     private static int charConvert(char src) {
         int r = BCConvert.qj2bj(src);
         return (r >= 'A' && r <= 'Z') ? r + 32 : r;
     }

 }

WordFilter.java

其中:

isContains :是否包含敏感词

doFilter:过滤敏感词

2、WordNode敏感词节点:

 package com.skyer.sensitivewdfilter;

 import java.util.LinkedList;
 import java.util.List;

 public class WordNode {

     private int value; // 节点名称

     private List<WordNode> subNodes; // 子节点

     private boolean isLast; // 默认false

     public WordNode(int value) {
         this.value = value;
     }

     public WordNode(int value, boolean isLast) {
         this.value = value;
         this.isLast = isLast;
     }

     /**
      * @return 就是传入的subNode
      */
     private WordNode addSubNode(final WordNode subNode) {
         if (subNodes == null)
             subNodes = new LinkedList<WordNode>();
         subNodes.add(subNode);
         return subNode;
     }

     /**
      * 有就直接返回该子节点, 没有就创建添加并返回该子节点
      */
     public WordNode addIfNoExist(final int value, final boolean isLast) {
         if (subNodes == null) {
             return addSubNode(new WordNode(value, isLast));
         }
         for (WordNode subNode : subNodes) {
             if (subNode.value == value) {
                 if (!subNode.isLast && isLast)
                     subNode.isLast = true;
                 return subNode;
             }
         }
         return addSubNode(new WordNode(value, isLast));
     }

     public WordNode querySub(final int value) {
         if (subNodes == null) {
             return null;
         }
         for (WordNode subNode : subNodes) {
             if (subNode.value == value)
                 return subNode;
         }
         return null;
     }

     public boolean isLast() {
         return isLast;
     }

     public void setLast(boolean isLast) {
         this.isLast = isLast;
     }

     @Override
     public int hashCode() {
         return value;
     }

 }

WordNode.java

3、测试类:

 package com.skyer.test;

 import org.junit.Test;

 import com.skyer.sensitivewdfilter.WordFilter;

 public class TestSensitivewd {

     @Test
     public void TestFilter() {
         String s = ""; // 这里写你要过滤的句子(我这里不能写,否则会给博客园屏蔽掉)
         System.out.println("解析问题: " + s);
         System.out.println("解析字数 : " + s.length());
         String re;
         long nano = System.nanoTime();
         re = WordFilter.doFilter(s);
         nano = (System.nanoTime() - nano);
         System.out.println("解析时间 : " + nano + "ns");
         System.out.println("解析时间 : " + nano / 1000000 + "ms");
         System.out.println(re);
         System.out.println();

         nano = System.nanoTime();
         System.out.println("是否包含敏感词: " + WordFilter.isContains(s));
         nano = (System.nanoTime() - nano);
         System.out.println("解析时间 : " + nano + "ns");
         System.out.println("解析时间 : " + nano / 1000000 + "ms");
     }

 }

TestSensitivewd.java

4、测试结果:

原文参考:http://blog.csdn.net/fengshizty/article/details/52373005

DFA知识:http://www.cnblogs.com/naaoveGIS/archive/2016/10/14/5960352.html

使用DFA算法对敏感词进行过滤的更多相关文章

  1. DFA算法实现敏感词过滤

    DFA算法:即确定有穷自动机,简单点说就是,它是是通过event和当前的state得到下一个state,即event+state=nextstate.理解为系统中有多个节点,通过传递进入的event, ...

  2. Java 利用DFA算法 屏蔽敏感词

    原文:http://www.open-open.com/code/view/1435214601278 import java.io.BufferedReader; import java.io.Fi ...

  3. 如何用Python实现敏感词的过滤

    题目要求如下: 从文件解析敏感词,从终端获取用户输入.根据敏感词对用户输入进行过滤.这里过滤需要考虑不止一个过滤词:即将读取的所有过滤词,放进一个列表,用屏蔽词检索用户输入,如果有屏蔽词,则将其替换为 ...

  4. Java实现敏感词过滤 - DFA算法

    Java实现DFA算法进行敏感词过滤 封装工具类如下: 使用前需对敏感词库进行初始化: SensitiveWordUtil.init(sensitiveWordSet); package cn.swf ...

  5. 敏感词过滤的算法原理之DFA算法

    参考文档 http://blog.csdn.net/chenssy/article/details/26961957 敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有 ...

  6. DFA和trie特里实现敏感词过滤(python和c语言)

    今天的项目是与完成python开展,需要使用做关键词检查,筛选分类,使用前c语言做这种事情.有了线索,非常高效,内存小了,检查快. 到达python在,第一个想法是pip基于外观的c语言python特 ...

  7. Java实现敏感词过滤

    敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的.前段时间我一个朋友(马上毕业,接触编程不久)要我帮他看一个文字过滤的东西,它说检索效率非常慢.我把它程序拿过来 ...

  8. Java实现敏感词过滤(转)

    敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的.前段时间我一个朋友(马上毕业,接触编程不久)要我帮他看一个文字过滤的东西,它说检索效率非常慢.我把它程序拿过来 ...

  9. Jsp敏感词过滤

    Jsp敏感词过滤 大部分论坛.网站等,为了方便管理,都进行了关于敏感词的设定. 在多数网站,敏感词一般是指带有敏感政治倾向(或反执政党倾向).暴力倾向.不健康色彩的词或不文明语,也有一些网站根据自身实 ...

随机推荐

  1. 性能测试培训:sql server性能测试分析局部变量的性能影响

    poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.在poptest的loadrunner的培训中,为了提高学员性能优化的经验,加入了 ...

  2. ReactJS入门:展示数据

    由于公司开发需要,博主利用闲暇的时间对ReactJS的基础知识进行了一些粗浅的认识和了解.博主对ReactJS的学习主要来自官网(http://reactjs.cn/react/docs/thinki ...

  3. SQL入门之条件表达式

    where子句和having子句主要是用来筛选符合条件的元组,其后紧跟的即为条件表达式. 0.and, or条件的连接 用法和一般编程语言一样,主要用于条件的拼接.and两边都为真,则结果为真.or两 ...

  4. 20144306《网络对抗》CAL_MSF基础运用

    1  实验内容 一个主动攻击,如ms08_067 一个针对浏览器的攻击,如ms11_050 一个针对客户端的攻击,如Adobe 成功应用任何一个辅助模块 2  实验过程记录 2.1 主动攻击MS08- ...

  5. SQL语句简单整理

    转载原文:http://blog.sina.com.cn/s/blog_48df31d901017c6o.html 1.用户 - 查看当前用户的缺省表空间 select username,defaul ...

  6. [Oracle]Audit(二)--清理Audit数据

    在上一篇,初步了解了Audit的作用以及如何使用Audit,本篇记录如何手动清理Audit数据. (一) 概述 Audit的数据主要存储在sys.aud$表中,该表默认位于system表空间中,我们根 ...

  7. mvc中DotNetOpenAuth实现了第三方应用访问自己的网站

    以yahoo为例吧,即从yahoo取得用户信息,存到自己的站点,实现了用户信息在一次录入多处共享的功能.以下是在点击了使用yahoo登录本站的链接后执行action:OpenId. ProviderU ...

  8. 使用了UnityEditor中的API,打包时却不能打包UnityEditor的问题

    前段时间写了一篇名叫<Unity使用Windows弹窗保存图片>的文章 然而现在项目进入了测试阶段 就在发布的时候,这个地方出问题了 问题出在using UnityEditor; 如上文章 ...

  9. 关于WebGIS开源解决方案的探讨(转载)

    1.背景 公司目前的多数项目采用的是ArcGIS产品+Oracle+WebLogic/Tomcat/APUSIC/WebShpere这样的架构.由于 公司从事的是政府项目,甲方单位普遍均采购有以上产品 ...

  10. getRequestURI()与getRequestURL()的区别

    引于: http://hi.baidu.com/cloudxpc request.getRequestURI() 返回值类似:/xuejava/requestdemo.jsprequest.getRe ...