《高效精准》敏感字&词过滤

在网上看到的大部分采用DFA算法,大概思路如下:

1:DFA采用Map的hash机制,将敏感词单个拆分,以第1个字符为key,其他值依旧使用map相连,形成了大map套用小map..

2:遍历需要过滤的字符串,获取每一个字符,根据get(key)来检测是否为敏感词。

我最开始是想到用正则来提取数据中的敏感数据,然后获取敏感字所在索引位置,再利用StringBuilder.replace(start,end,str)来替换,但经过测试发现使用正则有2个问题:

1:因为是正则要整串匹配,所以效率慢,同样3318个字符,平均在50毫秒以上

2:和敏感词与正则数据会产生冲突

所以就选择另一种思路:

1:遍历敏感词库,采用indexOf()来循环查询信息中是否含有此敏感数据

2:利用hashMap的来记录敏感在信息的key(起始位置)和最大的value(结束位置)

3:然后再遍历hashMap,得到每一组的start,end  再使用StringBuilder.replace(start,end,str)来替换敏感信息

4:被过滤的信息有3318个字符,平均在3~5毫秒内完成。

测试代码

	public void demo3(){
		SensitiveWord sw = new SensitiveWord("CensorWords1.txt");
		sw.InitializationWork();
		long startNumer = System.currentTimeMillis();
		String str = "太多的伤yuming感情怀也许只局限于饲养基地 荧幕中的情节,主人公尝试着去用某种方式渐渐的很潇洒地释自杀指南怀那些自己经历的伤感。"
				+ "然后法轮功 我们的扮演的角色就是跟随着主人yum公的喜红客联盟 怒于饲养基地 荧幕中的情节,主人公尝试着去用某种方式渐渐的很潇洒地释自杀指南怀那些自己经历的伤感。"
				+ "然后法轮功 我们的扮演的角色就是跟随着主人yum公的喜红客联盟 怒哀20于饲养基地 荧幕中的情节,主人公尝试着去用某种方式渐渐的很潇洒地释自杀指南怀那些自己经历的伤感。"
				+ "然后法轮功 我们的扮演的角色就是跟随着主人yum公的喜红客联盟 怒哀20哀2015/4/16 20152015/4/16乐而过于牵强的把自己的情感也附加于银幕情节中,然后感动就流泪,"
				+ "关, 人, 流, 电, 发, 情, 太, 限, 法轮功, 个人, 经, 色, 许, 公, 动, 地, 方, 基, 在, 上, 红, 强, 自杀指南, 制, 卡, 三级片, 一, 夜, 多, 手机, 于, 自,"
				+ "难过就躺在某一个人的怀里尽情的阐述心扉或者手机卡复制器一个人一杯红酒一部电影在夜三级片 深人静的晚上,关上电话静静的发呆着。";
		System.out.println("被检测字符长度:"+str.length());
		str = sw.filterInfo(str);
		long endNumber = System.currentTimeMillis();
		System.out.println("耗时(毫秒):"+(endNumber-startNumer));
		System.out.println("过滤之后:"+str);
	}

运行结果

代码如下:

package com.amov.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

/**
 *  敏感词过滤 工具类
 *
 * @author hubiao
 * @version 0.1
 * @CreateDate 2015年4月16日 15:28:32
 */
public class SensitiveWord {
	private StringBuilder replaceAll;//初始化
	private String encoding = "UTF-8";
	private String replceStr = "*";
	private int replceSize = 500;
	private String fileName = "CensorWords.txt";
	private List<String> arrayList;

	/**
	 * 文件要求路径在src或resource下,默认文件名为CensorWords.txt
	 * @param fileName 词库文件名(含后缀)
	 */
	public SensitiveWord(String fileName)
	{
		this.fileName = fileName;
	}

	/**
	 * @param replceStr 敏感词被转换的字符
	 * @param replceSize 初始转义容量
	 */
	public SensitiveWord(String replceStr,int replceSize)
	{
		this.replceStr = fileName;
		this.replceSize = replceSize;
	}

	public SensitiveWord()
	{
	}
	/**
	 * @param str 将要被过滤信息
	 * @return 过滤后的信息
	 */
	public String filterInfo(String str)
	{
		StringBuilder buffer = new StringBuilder(str);
		HashMap<Integer, Integer> hash = new HashMap<Integer, Integer>(arrayList.size());
		String temp;
		for(int x = 0; x < arrayList.size();x++)
		{
			temp = arrayList.get(x);
			int findIndexSize = 0;
			for(int start = -1;(start=buffer.indexOf(temp,findIndexSize)) > -1;)
			{
				findIndexSize = start+temp.length();//从已找到的后面开始找
				Integer mapStart = hash.get(start);//起始位置
				if(mapStart == null || (mapStart != null && findIndexSize > mapStart))//满足1个,即可更新map
				{
					hash.put(start, findIndexSize);
				}
			}
		}
		Collection<Integer> values = hash.keySet();
		for(Integer startIndex : values)
		{
			Integer endIndex = hash.get(startIndex);
			buffer.replace(startIndex, endIndex, replaceAll.substring(0,endIndex-startIndex));
		}
		hash.clear();
		return buffer.toString();
	}
	/**
	 *   初始化敏感词库
	 */
	public void InitializationWork()
	{
		replaceAll = new StringBuilder(replceSize);
		for(int x=0;x < replceSize;x++)
		{
			replaceAll.append(replceStr);
		}
		//加载词库
		arrayList = new ArrayList<String>();
		InputStreamReader read = null;
		BufferedReader bufferedReader = null;
		try {
			read = new InputStreamReader(SensitiveWord.class.getClassLoader().getResourceAsStream(fileName),encoding);
			bufferedReader = new BufferedReader(read);
			for(String txt = null;(txt = bufferedReader.readLine()) != null;){
				if(!arrayList.contains(txt))
					arrayList.add(txt);
		    }
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				if(null != bufferedReader)
				bufferedReader.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(null != read)
				read.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	public StringBuilder getReplaceAll() {
		return replaceAll;
	}
	public void setReplaceAll(StringBuilder replaceAll) {
		this.replaceAll = replaceAll;
	}
	public String getReplceStr() {
		return replceStr;
	}
	public void setReplceStr(String replceStr) {
		this.replceStr = replceStr;
	}
	public int getReplceSize() {
		return replceSize;
	}
	public void setReplceSize(int replceSize) {
		this.replceSize = replceSize;
	}
	public String getFileName() {
		return fileName;
	}
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	public List<String> getArrayList() {
		return arrayList;
	}
	public void setArrayList(List<String> arrayList) {
		this.arrayList = arrayList;
	}
	public String getEncoding() {
		return encoding;
	}
	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}

}

时间: 2024-11-08 03:36:04

《高效精准》敏感字&词过滤的相关文章

转:Java实现敏感词过滤

敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的.前段时间我一个朋友(马上毕业,接触编程不久)要我帮他看一个文字过滤的东西,它说检索效率非常慢.我把它程序拿过来一看,整个过程如下:读取敏感词库.如果HashSet集合中,获取页面上传文字,然后进行匹配.我就想这个过程肯定是非常慢的.对于他这个没有接触的人来说我想也只能想到这个,更高级点就是正则表达式.但是非常遗憾,这两种方法都是不可行的.当然,在我意识里没有我也没有认知到那个算法可以解决问题,但是Googl

Java实现敏感词过滤

敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的.前段时间我一个朋友(马上毕业,接触编程不久)要我帮他看一个文字过滤的东西,它说检索效率非常慢.我把它程序拿过来一看,整个过程如下:读取敏感词库.如果HashSet集合中,获取页面上传文字,然后进行匹配.我就想这个过程肯定是非常慢的.对于他这个没有接触的人来说我想也只能想到这个,更高级点就是正则表达式.但是非常遗憾,这两种方法都是不可行的.当然,在我意识里没有我也没有认知到那个算法可以解决问题,但是Googl

Java实现敏感词过滤(转)

敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的.前段时间我一个朋友(马上毕业,接触编程不久)要我帮他看一个文字过滤的东西,它说检索效率非常慢.我把它程序拿过来一看,整个过程如下:读取敏感词库.如果HashSet集合中,获取页面上传文字,然后进行匹配.我就想这个过程肯定是非常慢的.对于他这个没有接触的人来说我想也只能想到这个,更高级点就是正则表达式.但是非常遗憾,这两种方法都是不可行的.当然,在我意识里没有我也没有认知到那个算法可以解决问题,但是Googl

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

参考文档 http://blog.csdn.net/chenssy/article/details/26961957 敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的.前段时间我一个朋友(马上毕业,接触编程不久)要我帮他看一个文字过滤的东西,它说检索效率非常慢.我把它程序拿过来一看,整个过程如下:读取敏感词库.如果HashSet集合中,获取页面上传文字,然后进行匹配.我就想这个过程肯定是非常慢的.对于他这个没有接触的人来说我想也只能想到这个,更高级点就是正

转:鏖战双十一-阿里直播平台面临的技术挑战(webSocket, 敏感词过滤等很不错)

转自:http://www.infoq.com/cn/articles/alibaba-broadcast-platform-technology-challenges 鏖战双十一-阿里直播平台面临的技术挑战 作者 陈康贤 发布于 2016年1月28日 | 2 讨论 分享到:微博微信FacebookTwitter有道云笔记邮件分享 稍后阅读 我的阅读清单 前言:一直以来双十一都是以交易为重心,今年当然也是如此,但是这并不妨碍万能的淘宝将双十一打造的让用户更欢乐.体验更丰富.玩法更多样.内容更有趣

DFA和trie字典树实现敏感词过滤(python和c语言)

现在做的项目都是用python开发,需要用做关键词检查,过滤关键词,之前用c语言做过这样的事情,用字典树,蛮高效的,内存小,检查快. 到了python上,第一想法是在pip上找一个基于c语言的python字典树模块,可惜没找到合适的,如果我会用c写python模块的话,我就自己写一个了,可惜我还不具备这个能力, 只能用python写了,性能差一点就差点吧,内存多一点也无所谓了. 用搜索引擎看CSDN上的网友的用python实现的DFA,再参照自己以前用c语言写过的字典树,有些不大对,就自己写了一

Jsp敏感词过滤

Jsp敏感词过滤 大部分论坛.网站等,为了方便管理,都进行了关于敏感词的设定. 在多数网站,敏感词一般是指带有敏感政治倾向(或反执政党倾向).暴力倾向.不健康色彩的词或不文明语,也有一些网站根据自身实际情况,设定一些只适用于本网站的特殊敏感词. 比如,当你发贴的时候带有某些事先设定的词时,这个贴是不能发出的.或者这个词被自动替换为星号(*)或叉号(X)等,或者说是被和谐掉了. 在我看来敏感词过滤最重要的是在写过滤词汇的算法,如何过滤出大批量的敏感词,我感觉DFA的思想不错 DFA简介 在实现文字

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

今天的项目是与完成python开展,需要使用做关键词检查,筛选分类,使用前c语言做这种事情.有了线索,非常高效,内存小了,检查快. 到达python在,第一个想法是pip基于外观的c语言python特里模块.不幸的是,我们没有找到一个合适的,假设我会用c书写python模块的话.就自己写一个了,可惜我还不具备这个能力. 仅仅能用python写了,性能差一点就差点吧,内存多一点也无所谓了. 用搜索引擎看CSDN上的网友的用python实现的DFA,再參照自己曾经用c语言写过的字典树.有些不大对,就

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

小Alan在最近的开发中遇到了敏感词过滤,便去网上查阅了很多敏感词过滤的资料,在这里也和大家分享一下自己的理解. 在写之前,小Alan给大家推荐一篇来自http://cmsblogs.com/?p=1031的博文,也会参考部分内容来描述博文. 敏感词过滤应该是不用给大家过多的解释吧?讲白了就是你在项目中输入某些字(比如输入xxoo相关的文字时)时要能检测出来,很多项目中都会有一个敏感词管理模块,在敏感词管理模块中你可以加入敏感词,然后根据加入的敏感词去过滤输入内容中的敏感词并进行相应的处理,要么