using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace SensitiveWordFilter
{
public class SensitiveWord
{
private static readonly char IsEndChar = '$'; /**
* 初始化敏感词库<br>
* 将敏感词加入到HashMap中<br>
* 构建DFA算法模型
*
* @author dxm
*
*/
public class SensitiveWordInit
{ // 字符编码
private static readonly String ENCODING = "UTF-8"; /**
* 初始化敏感字库
*
* @return
*/
public Dictionary<char, object> initKeyWord()
{ // 读取敏感词库
HashSet<String> wordSet = readSensitiveWordFile(); // 将敏感词库加入到HashMap中
return addSensitiveWordToHashMap(wordSet);
} /**
* 读取敏感词库,将敏感词放入HashSet中,构建一个DFA算法模型:<br>
* 中 = {
* isEnd = 0
* 国 = {
* isEnd = 1
* 人 = {
* isEnd = 0
* 民 = {
* isEnd = 1
* }
* }
* 男 = {
* isEnd = 0
* 人 = {
* isEnd = 1
* }
* }
* }
* }
* 五 = {
* isEnd = 0
* 星 = {
* isEnd = 0
* 红 = {
* isEnd = 0
* 旗 = {
* isEnd = 1
* }
* }
* }
* }
*/
private Dictionary<char, object> addSensitiveWordToHashMap(HashSet<String> wordSet)
{ // 初始化敏感词容器,减少扩容操作
Dictionary<char, object> wordMap = new Dictionary<char, object>(wordSet.Count); foreach (String word in wordSet)
{
IDictionary<char, object> nowMap = wordMap;
for (int i = 0; i < word.Length; i++)
{ // 转换成char型
char keyChar = word[i]; if (keyChar == IsEndChar)
continue; Object tempMap;
// 获取
nowMap.TryGetValue(keyChar, out tempMap); // 如果存在该key,直接赋值
if (tempMap != null)
{
nowMap = (Dictionary<char, object>)tempMap;
} // 不存在则,则构建一个map,同时将isEnd设置为0,因为他不是最后一个
else { // 设置标志位
Dictionary<char, object> newMap = new Dictionary<char, object>();
newMap.Add(IsEndChar, "0"); // 添加到集合
nowMap.Add(keyChar, newMap);
nowMap = newMap;
} // 最后一个
if (i == word.Length - 1)
{
nowMap[IsEndChar] = "1";
}
}
} return wordMap;
} /**
* 读取敏感词库中的内容,将内容添加到SortedSet集合中
*
* @return
* @throws Exception
*/
private HashSet<String> readSensitiveWordFile()
{
HashSet<String> wordSet = new HashSet<string>();
string content = File.ReadAllText("dic.txt", Encoding.GetEncoding(ENCODING));
using (StringReader sr = new StringReader(content))
{
string s;
while ((s = sr.ReadLine()) != null)
{
wordSet.Add(s);
}
}
return wordSet;
}
} public class SensitivewordFilter
{ private Dictionary<char, object> sensitiveWordMap = null; // 最小匹配规则
public static int minMatchTYpe = 1; // 最大匹配规则
public static int maxMatchType = 2; // 单例
private static SensitivewordFilter inst = null; /**
* 构造函数,初始化敏感词库
*/
private SensitivewordFilter()
{
sensitiveWordMap = new SensitiveWordInit().initKeyWord();
} /**
* 获取单例
*
* @return
*/
public static SensitivewordFilter getInstance()
{
if (null == inst)
{
inst = new SensitivewordFilter();
}
return inst;
} /**
* 判断文字是否包含敏感字符
*
* @param txt
* @param matchType
* @return
*/
public bool isContaintSensitiveWord(String txt, int matchType = 1)
{
bool flag = false;
for (int i = 0; i < txt.Length; i++)
{ // 判断是否包含敏感字符
int matchFlag = this.CheckSensitiveWord(txt, i, matchType); // 大于0存在,返回true
if (matchFlag > 0)
{
flag = true;
}
}
return flag;
} /**
* 获取文字中的敏感词
*
* @param txt
* @param matchType
* @return
*/
public HashSet<String> getSensitiveWord(String txt, int matchType = 1)
{
HashSet<String> sensitiveWordList = new HashSet<String>(); for (int i = 0; i < txt.Length; i++)
{ // 判断是否包含敏感字符
int length = CheckSensitiveWord(txt, i, matchType); // 存在,加入list中
if (length > 0)
{
sensitiveWordList.Add(txt.Substring(i, length)); // 减1的原因,是因为for会自增
i = i + length - 1;
}
} return sensitiveWordList;
} /**
* 替换敏感字字符
*
* @param txt
* @param matchType
* @param replaceChar
* @return
*/
public String replaceSensitiveWord(String txt, String replaceChar, int matchType = 1)
{
StringBuilder sb = new StringBuilder(txt);
for (int i = 0; i < txt.Length; i++)
{ // 判断是否包含敏感字符
int length = CheckSensitiveWord(txt, i, matchType); // 存在,加入list中
if (length > 0)
{
var ttxt = txt.Substring(i, length);
sb.Replace(ttxt, getReplaceChars(replaceChar, ttxt.Length), i, length); // 减1的原因,是因为for会自增
i = i + length - 1;
}
} return sb.ToString();
} /**
* 获取替换字符串
*
* @param replaceChar
* @param length
* @return
*/
private String getReplaceChars(String replaceChar, int length)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++)
{
sb.Append(replaceChar);
} return sb.ToString();
} /**
* 检查文字中是否包含敏感字符,检查规则如下:<br>
* 如果存在,则返回敏感词字符的长度,不存在返回0
*
* @param txt
* @param beginIndex
* @param matchType
* @return
*/
public int CheckSensitiveWord(String txt, int beginIndex, int matchType)
{ // 敏感词结束标识位:用于敏感词只有1位的情况
bool flag = false; // 匹配标识数默认为0
int matchFlag = 0;
Dictionary<char, object> nowMap = sensitiveWordMap;
int tempFlag = 0;
Dictionary<char, object> tempMapForBack = new Dictionary<char, object>();
int len = txt.Length;
for (int i = beginIndex; i < len; i++)
{
char word = txt[i]; if (word == IsEndChar)
continue; // 获取指定key
Object tempMap;
// 获取
nowMap.TryGetValue(word, out tempMap); if (tempFlag == 0)
tempMapForBack = nowMap; // 如果存在该key,直接赋值
if (tempMap != null)
{
nowMap = (Dictionary<char, object>)tempMap;
}
else
{
if (tempFlag > 0)
{
matchFlag = matchFlag - (i - tempFlag);
i = tempFlag - 1;
nowMap = tempMapForBack;
continue;
}
else
{
nowMap = null;
}
} // 存在,则判断是否为最后一个
if (nowMap != null)
{ // 找到相应key,匹配标识+1
matchFlag++; object value; if (nowMap.TryGetValue(IsEndChar, out value))
{
if (value is string)
{
// 如果为最后一个匹配规则,结束循环,返回匹配标识数
if ("1" == (string)value)
{
if (nowMap.Keys.Count == 1 || tempFlag != 0 || i == len - 1)
{
// 结束标志位为true
flag = true; // 最小规则,直接返回,最大规则还需继续查找
if (SensitivewordFilter.minMatchTYpe == matchType)
{
break;
}
}
else
{
tempFlag = i;
}
}
}
}
}
// 不存在,直接返回
else
{
break;
}
} // 长度必须大于等于1,为词
if (matchFlag < 2 || !flag)
{
matchFlag = 0;
}
return matchFlag;
}
}
}
} using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace SensitiveWordFilter
{
class Program
{
static void Main(string[] args)
{
SensitiveWord.SensitivewordFilter filter = SensitiveWord.SensitivewordFilter.getInstance();
String txt = "$fuckfuck you你麻痹e菜太菜了fuckyou从飞啊 fuck you";
String hou = filter.replaceSensitiveWord(txt, "*");
Console.WriteLine("替换前的文字为:" + txt);
Console.WriteLine("替换后的文字为:" + hou);
Console.ReadKey();
}
}
}

敏感词汇过滤DFA算法的更多相关文章

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

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

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

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

  3. JavaWeb 之 Filter 敏感词汇过滤案例

    需求: 1. 对day17_case案例录入的数据进行敏感词汇过滤 2. 敏感词汇参考 src路径下的<敏感词汇.txt> 3. 如果是敏感词汇,替换为 *** 分析: 1. 对reque ...

  4. 敏感词过滤的算法原理之 Aho-Corasick 算法

    参考文档 http://www.hankcs.com/program/algorithm/implementation-and-analysis-of-aho-corasick-algorithm-i ...

  5. DFA算法之内容敏感词过滤

    DFA 算法是通过提前构造出一个 树状查找结构,之后根据输入在该树状结构中就可以进行非常高效的查找. 设我们有一个敏感词库,词酷中的词汇为:我爱你我爱他我爱她我爱你呀我爱他呀我爱她呀我爱她啊 那么就可 ...

  6. Java实现敏感词过滤 - IKAnalyzer中文分词工具

    IKAnalyzer 是一个开源的,基于java语言开发的轻量级的中文分词工具包. 官网: https://code.google.com/archive/p/ik-analyzer/ 本用例借助 I ...

  7. java实现敏感词过滤(DFA算法)

    小Alan在最近的开发中遇到了敏感词过滤,便去网上查阅了很多敏感词过滤的资料,在这里也和大家分享一下自己的理解. 敏感词过滤应该是不用给大家过多的解释吧?讲白了就是你在项目中输入某些字(比如输入xxo ...

  8. Jsp敏感词过滤

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

  9. Java实现敏感词过滤

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

随机推荐

  1. springsecurity 源码解读之 AnonymousAuthenticationFilter

    我们知道springsecutity 是通过一系列的 过滤器实现的,我们可以看看这系列的过滤器到底长成什么样子呢? 一堆过滤器,这个过滤器的设计设计上是 责任链设计模式. 这里我们可以看到有一个 An ...

  2. s6-7 TCP 传输策略

    TCP 传输策略 防止黏包现象的出现 当窗口数为 0 时,发送者不能正常发送数据段,除非: -Urgent数据.比如,用户想杀掉远端机器上的进程的时候,可以发送数据 -发送者可以发送一个字节的数据段, ...

  3. Springboot单例模式实战封装json转换

    一.定义 保证一个类仅有一个实例,并提供一个全局访问点. 二.优点 (1)在内存里只有一个实例,减少了内存开销      (2)可以避免对资源的多重占用      (3)设置全局访问点,严格控制访问 ...

  4. 浮点数运算结果不精确,以及用String来构造BigDecimal进行浮点数精确计算

    1.浮点数运算结果不精确 先看如下代码 System.out.println(1.0 - 0.8); System.out.println(0.2 + 0.1); System.out.println ...

  5. Delphi XE7试用记录2

    Delphi XE7试用记录2 万一博客中介绍了不少Delphi7以后的新功能测试,想跟着测试一下.每次测试建立一个工程,在窗体上放几个按钮,测试几个相关的功能,这样虽然简单明了,但日后查阅起来不方便 ...

  6. 29.vector

    对于List接口这里还介绍一个它的实现类Vector,Vector 类可以实现可增长的对象数组. Vector可以实现可增长的对象数组.与数组一样,它包含可以使用整数索引进行访问的组件.不过,Vect ...

  7. html基础知识梳理

    1.浏览器内核 补充:blink为Google与Opera共同开发. 2.web标准 web标准为w3c和其他标准化组织制定的一系列标准的集合.(标签闭合.小写.不乱嵌套,使用外链css/js;结构行 ...

  8. PB开发境界 多个DW进行update

      多个DW进行update //菜鸟代码dw_1.Update()dw_2.Update()初级代码IF dw_1.Update() = 1 And dw_2.Update() = 1 THEN  ...

  9. InnoDB Insert Buffer(插入缓冲)

    InnoDB Insert Buffer(插入缓冲) 每个存储存储引擎自身都有自己的特性(决定性能以及更高可靠性),而InnoDB的关键特性有: 插入缓冲(Insert Buffer)-->Ch ...

  10. 控制页面打印的2种方法(css3的media媒体查询和window.print())

    在实际开发中,有时可能会有打印的需求.下面我总结了2种打印的方法,希望对各位小伙伴有所帮助. ①:直接用window.print()方法就可以打印整个页面,下面是一个小demo <!DOCTYP ...