敏感词汇过滤(不区分大小写)

最近项目中,用户评论内容需要屏蔽敏感词汇,从网上总结以下方法,(不区分大小写,如想设置大小写敏感,可以把代码中content..toLowerCase()去掉).具体看代码:

1.读取敏感词汇文档

<span style="font-size:18px;">package com.blemall.wizlife.util.sensitive;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * @Description: 初始化敏感词库,将敏感词加入到HashMap中,构建DFA算法模型
 * @Project:test
 * @version 1.0
 */
public class SensitiveWordInit {
	private String ENCODING = "UTF-8";    //字符编码
	@SuppressWarnings("rawtypes")
	public HashMap sensitiveWordMap;

	public SensitiveWordInit(){
		super();
	}

	@SuppressWarnings("rawtypes")
	public Map initKeyWord(){
		try {
			//读取敏感词库
			Set<String> keyWordSet = readSensitiveWordFile();
			//将敏感词库加入到HashMap中
			addSensitiveWordToHashMap(keyWordSet);
			//spring获取application,然后application.setAttribute("sensitiveWordMap",sensitiveWordMap);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sensitiveWordMap;
	}

	/**
	 * 读取敏感词库,将敏感词放入HashSet中,构建一个DFA算法模型:<br>
	 * 中 = {
	 *      isEnd = 0
	 *      国 = {<br>
	 *      	 isEnd = 1
	 *           人 = {isEnd = 0
	 *                民 = {isEnd = 1}
	 *                }
	 *           男  = {
	 *           	   isEnd = 0
	 *           		人 = {
	 *           			 isEnd = 1
	 *           			}
	 *           	}
	 *           }
	 *      }
	 *  五 = {
	 *      isEnd = 0
	 *      星 = {
	 *      	isEnd = 0
	 *      	红 = {
	 *              isEnd = 0
	 *              旗 = {
	 *                   isEnd = 1
	 *                  }
	 *              }
	 *      	}
	 *      }
	 * @param keyWordSet  敏感词库
	 * @version 1.0
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private void addSensitiveWordToHashMap(Set<String> keyWordSet) {
		sensitiveWordMap = new HashMap(keyWordSet.size());     //初始化敏感词容器,减少扩容操作
		String key = null;
		Map nowMap = null;
		Map<String, String> newWorMap = null;
		//迭代keyWordSet
		Iterator<String> iterator = keyWordSet.iterator();
		while(iterator.hasNext()){
			key = iterator.next();    //关键字
			nowMap = sensitiveWordMap;
			for(int i = 0 ; i < key.length() ; i++){
				char keyChar = key.charAt(i);       //转换成char型
				Object wordMap = nowMap.get(keyChar);       //获取

				if(wordMap != null){        //如果存在该key,直接赋值
					nowMap = (Map) wordMap;
				}
				else{     //不存在则,则构建一个map,同时将isEnd设置为0,因为他不是最后一个
					newWorMap = new HashMap<String,String>();
					newWorMap.put("isEnd", "0");     //不是最后一个
					nowMap.put(keyChar, newWorMap);
					nowMap = newWorMap;
				}

				if(i == key.length() - 1){
					nowMap.put("isEnd", "1");    //最后一个
				}
			}
		}
	}

	/**
	 * 读取敏感词库中的内容,将内容添加到set集合中
	 * @author chenming
	 * @date 2014年4月20日 下午2:31:18
	 * @return
	 * @version 1.0
	 * @throws Exception
	 */
	@SuppressWarnings("resource")
	private Set<String> readSensitiveWordFile() throws Exception{
		Set<String> set = null;
		ClassLoader loader=SensitiveWordInit.class.getClassLoader();
		URL url=loader.getResource("/SensitiveWord.txt");
		String filePath =url.getPath();
		File file=new File(filePath);
		InputStreamReader read = new InputStreamReader(new FileInputStream(file),ENCODING);
		try {
			if(file.isFile() && file.exists()){      //文件流是否存在
				set = new HashSet<String>();
				BufferedReader bufferedReader = new BufferedReader(read);
				String txt = null;
				while((txt = bufferedReader.readLine()) != null){    //读取文件,将文件内容放入到set中
					set.add(txt);
				}
			}
			else{         //不存在抛出异常信息
				throw new Exception("敏感词库文件不存在");
			}
		} catch (Exception e) {
			throw e;
		}finally{
			read.close();     //关闭文件流
		}
		return set;
	}
}
</span>

2.具体方法:

replaceSensitiveWord(String content(内容),int matchType(匹配规则),String replaceChar(替换词))
<span style="font-size:18px;">package com.blemall.wizlife.util.sensitive;

import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

@Component
public class SensitivewordFilter {
	@SuppressWarnings("rawtypes")
	private Map sensitiveWordMap = null;
	public static int minMatchTYpe = 1;      //最小匹配规则
	public static int maxMatchType = 2;      //最大匹配规则

	/**
	 * 构造函数,初始化敏感词库
	 */
	public SensitivewordFilter(){
		sensitiveWordMap = new SensitiveWordInit().initKeyWord();
	}

	/**
	 * 判断文字是否包含敏感字符
	 * @param txt  文字
	 * @param matchType  匹配规则 1:最小匹配规则,2:最大匹配规则
	 * @return 若包含返回true,否则返回false
	 * @version 1.0
	 */
	public boolean isContaintSensitiveWord(String txt,int matchType){
		boolean flag = false;
		for(int i = 0 ; i < txt.length() ; i++){
			int matchFlag = this.CheckSensitiveWord(txt, i, matchType); //判断是否包含敏感字符
			if(matchFlag > 0){    //大于0存在,返回true
				flag = true;
			}
		}
		return flag;
	}

	/**
	 * 获取文字中的敏感词
	 * @param txt 文字
	 * @param matchType 匹配规则 1:最小匹配规则,2:最大匹配规则
	 * @return
	 * @version 1.0
	 */
	public Set<String> getSensitiveWord(String txt , int matchType){
		Set<String> sensitiveWordList = new HashSet<String>();

		for(int i = 0 ; i < txt.length() ; i++){
			int length = CheckSensitiveWord(txt, i, matchType);    //判断是否包含敏感字符
			if(length > 0){    //存在,加入list中
				sensitiveWordList.add(txt.substring(i, i+length));
				i = i + length - 1;    //减1的原因,是因为for会自增
			}
		}

		return sensitiveWordList;
	}

	/**
	 * @date 2014年4月20日 下午5:12:07
	 * @param content
	 * @param matchType
	 * @param replaceChar 替换字符,默认*
	 * @version 1.0
	 */
	public String replaceSensitiveWord(String content,int matchType,String replaceChar){
		String resultTxt = content;
		Set<String> set = getSensitiveWord(content.toLowerCase(), matchType);//将输入内容先转换为小写,获取所有的敏感词
		Iterator<String> iterator = set.iterator();
		String word = null;
		String replaceString = null;
		while (iterator.hasNext()) {
			word = iterator.next();
			word="(?i)"+word;
			replaceString = getReplaceChars(replaceChar, word.length());
			resultTxt = resultTxt.replaceAll(word, replaceString);
		}
		return resultTxt;
	}

	/**
	 * 获取替换字符串
	 * @param replaceChar
	 * @param length
	 * @return
	 * @version 1.0
	 */
	private String getReplaceChars(String replaceChar,int length){
		String resultReplace = replaceChar;
		for(int i = 1 ; i < length ; i++){
			resultReplace += replaceChar;
		}

		return resultReplace;
	}

	/**
	 * 检查文字中是否包含敏感字符,检查规则如下:<br>
	 * @param txt
	 * @param beginIndex
	 * @param matchType
	 * @return,如果存在,则返回敏感词字符的长度,不存在返回0
	 * @version 1.0
	 */
	@SuppressWarnings({ "rawtypes"})
	public int CheckSensitiveWord(String txt,int beginIndex,int matchType){
		boolean  flag = false;    //敏感词结束标识位:用于敏感词只有1位的情况
		int matchFlag = 0;     //匹配标识数默认为0
		char word = 0;
		Map nowMap = sensitiveWordMap;
		for(int i = beginIndex; i < txt.length() ; i++){
			word = txt.charAt(i);
			nowMap = (Map) nowMap.get(word);     //获取指定key
			if(nowMap != null){     //存在,则判断是否为最后一个
				matchFlag++;     //找到相应key,匹配标识+1
				if("1".equals(nowMap.get("isEnd"))){       //如果为最后一个匹配规则,结束循环,返回匹配标识数
					flag = true;       //结束标志位为true
					if(SensitivewordFilter.minMatchTYpe == matchType){    //最小规则,直接返回,最大规则还需继续查找
						break;
					}
				}
			}
			else{     //不存在,直接返回
				break;
			}
		}
		if(matchFlag < 2 || !flag){        //长度必须大于等于1,为词
			matchFlag = 0;
		}
		return matchFlag;
	}

}
</span>

附件:敏感词汇表(SensitiveWord.txt)

时间: 2024-08-07 20:31:05

敏感词汇过滤(不区分大小写)的相关文章

过滤敏感词汇

第一种方式 创建敏感词汇文件 首先需要准备一个txt格式的文件用于存放需要过滤的敏感词汇,这个文件放到resources资源文件的根目录 java代码 service代码 package com.ccytsoft.wkc.service; import lombok.Data; import org.springframework.stereotype.Service; import java.io.BufferedReader; import java.io.IOException; impo

js过滤检测敏感词汇

html: <textarea rows="10" cols="100" id="myDiv"></textarea> <button id="getFile" onclick="yz()">校验文字</button> js: //禁止多次请求 let stRs=sessionStorage.getItem('stRs')?sessionStorage.get

JavaWeb 过滤敏感词汇

提交的表单数据,常常要检查有没有敏感词汇,如果有,需要给出提示,或者替换为*. 检查.替换敏感词汇有3种常用的方式 (1)在Servlet中操作. (2)在Filter中先检查.如果要替换敏感词汇,request没有setParameter()方法重新设置请求参数,怎么向Servlet中传递替换后的请求参数?使用request.setAttribute()把这些修改后的请求参数放到request域中即可. (3)在Filter中创建request的代理,增强getParameter()方法,然后

Jsp敏感词过滤

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

转:Java实现敏感词过滤

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

Java实现敏感词过滤

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

Java实现敏感词过滤(转)

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

敏感词过滤

敏感词过滤是很多网站.论坛常用的功能,一下为相关文章: 1.关于java中敏感词检测的一些总结 2.Java 利用DFA算法 屏蔽敏感词 3.Java实现敏感词过滤--DFA算法

敏感词过滤,js封装class选择器:

敏感词过滤: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script> window.onload = function () { var oBtn = document.getElementById("btn"); var aT = d