读取敏感词库内容,讲某段字符里面的敏感词替换成*

敏感词过滤SensitivewordFilter.java

package aaa;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description: 敏感词过滤
 * @Project:test
 * @Author : chenming
 * @Date : 2014年4月20日 下午4:17:15
 * @version 1.0
 */
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();
    }

    /**
     * 判断文字是否包含敏感字符
     *
     * @author chenming
     * @date 2014年4月20日 下午4:28:30
     * @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;
    }

    /**
     * 获取文字中的敏感词
     *
     * @author chenming
     * @date 2014年4月20日 下午5:10:52
     * @param txt
     *            文字
     * @param matchType
     *            匹配规则&nbsp;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;
    }

    /**
     * 替换敏感字字符
     *
     * @author chenming
     * @date 2014年4月20日 下午5:12:07
     * @param txt
     * @param matchType
     * @param replaceChar
     *            替换字符,默认*
     * @version 1.0
     */
    public String replaceSensitiveWord(String txt, int matchType, String replaceChar) {
        String resultTxt = txt;
        Set<String> set = getSensitiveWord(txt, matchType); // 获取所有的敏感词
        Iterator<String> iterator = set.iterator();
        String word = null;
        String replaceString = null;
        while (iterator.hasNext()) {
            word = iterator.next();
            replaceString = getReplaceChars(replaceChar, word.length());
            resultTxt = resultTxt.replaceAll(word, replaceString);
        }

        return resultTxt;
    }

    /**
     * 获取替换字符串
     *
     * @author chenming
     * @date 2014年4月20日 下午5:21:19
     * @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>
     *
     * @author chenming
     * @date 2014年4月20日 下午4:31:03
     * @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;
    }

    public static void main(String[] args) {
        SensitivewordFilter filter = new SensitivewordFilter();
        String string = "反共多少分开了家里打扫房间丽舍大街路口反抗螺丝钉警方立刻圣诞节快乐房里看电视克利夫兰科达斯科拉菲快乐圣诞节发卡量达斯科拉反G该罚的辅导感到十分个地方鬼地方感动发给地方鬼地方鬼地方鬼地方感到十分鬼地方感到十分鬼地方感动中共地方鬼地方感到十分感到十分鬼地方广东省打手犯规大塞弗鬼地方感到十分古典风格对方是个共产梵蒂冈地方感动独立分开计算的离开家连锁店接连发生的离开分快乐圣诞节分卡洛斯的离开离开家得了三等奖路口发生的离开洗脑辅导告诉对方感到十分感动发给三等份鬼地方感到十分鬼地方鬼地方地方GCD鬼地方梵蒂冈地方该罚的鬼地方鬼地方鬼地方鬼地方给对方是个打手犯规第四个 CCP地方鬼地方感动大放送感到十分感到十分光的反射感到十分告诉对方感到十分广东省GONG党 豆腐干大塞弗感到十分告诉对方告诉对方感到十分感到十分敢死队大塞弗网特 梵蒂冈打手犯规打手犯规对方是个大放送给对方是个地方暴政 梵蒂冈地方广东省反攻倒算豆腐干对方是个豆腐干大放送";

        Set<String> set = filter.getSensitiveWord(string, 1);
        /*for (String word : set) {
            filter.replaceSensitiveWord(string, word, "***");
            string = string.replace(word, "***");
        }*/
    }
}

SensitiveWordInit.java

package aaa;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
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
 * @Author : lifei.pan
 * @Date : 2014年4月20日 下午2:27:06
 * @version 1.0
 */
public class SensitiveWordInit {
    private String ENCODING = "utf-8"; // 字符编码
    @SuppressWarnings("rawtypes")
    public HashMap sensitiveWordMap;

    public SensitiveWordInit() {
        super();
    }

    /**
     * @author chenming
     * @date 2014年4月20日 下午2:28:32
     * @version 1.0
     */
    @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
     * } } } }
     *
     * @author chenming
     * @date 2014年4月20日 下午3:04:20
     * @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;

        File file = new File("E:\\skywork\\aaa\\src\\keyword_bak.txt"); // 读取文件
        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;
    }
}
时间: 2024-10-17 11:44:50

读取敏感词库内容,讲某段字符里面的敏感词替换成*的相关文章

深蓝词库转换2.8发布&mdash;&mdash;支持微软拼音自学习词库导入导出

Win10自带的微软拼音一直以来有不少忠粉,但是词库导入导出一直是一个问题,因为微软拼音的自学习词库是自有格式,没有对外开放,所以一直没有解决.只能通过自定义短语的形式导入其他输入法的词库到微软拼音中. 最近经过网友的提醒,再自我研究了几晚上,终于把微软拼音的自学习词库导入导出解决了. 本次2.8版本的发布主要包含了以下更新: 微软拼音自学习词库的导入和导出. 转换词库时如果某些词条无法转换,通过错误窗口提示错误信息. 增强了微软拼音自定义短语对多种双拼方案的支持. 修改持续集成的实现方式,使用

极点五笔词库DIY

2004年没啥好的拼音输入法,试了清华紫光输入法一段时间,也相当不满意, 于是在2005年开始学五笔,很快就选定极点五笔了, 使用过程中没啥不满意的,反而还有惊喜,主要就是快捷码表吧,很爽. 一直就这么用着,期间发现有些重码,还有编码设定的不合理, 但是一直没太上心,2016年开始留意了下,想DIY词库和码表,发现问题有: 1.[用户码表]如果修改后,极点会自动重新导入,但是之前用户调整的字词顺序被重置了. 2.把词库导出到txt文件(或网上下载其他词库),以后就维护这个txt文件,修改后用系统

郑码词库制作for百度输入法

一.百度手机输入法 ①原材料:郑码(安静词库超级郑码群修正版) ②以上词库为极点码表格式,需要将其转化为百度手机输入法支持的格式. ③用 notepad++ 编辑码表,去掉表头及~,^,!符号.如图:                 ④用 多多码表编辑器V3.2 将其换化为 QQ码表 格式,选择"菜单→工具→常见码表格式转换",如图:                   ⑤用多多码表的 "高级码表格式转换"将QQ码表转化为百度格式(期间电脑会卡5分钟,要有耐心).

中州韵输入法导入搜狗词库

rime是一个非常优秀的输入法,linux平台下的反应速度远超搜狗,也没有隐私风险.2012年开始接触它,到后来抛弃了它,因为rime自带的词库真的太弱了,也懒得折腾.最近发现一个词库转换软件叫imewlconverter,于是发现rime导入其他输入法(比如搜狗)的词库其实还挺方便的. 要导入词库需要两个文件: 1. luna_pinyin_simp.custom.yaml 是配置文件 rime在部署的时候会自动加载.因为我用的是明月简体schema,所以是这个名字.如果你用的是明月schem

如何创造自己的数据字典(词库转换工具的使用)

对于很多做大数据的人来说,我们需要大量的数据字典作为我们准确分析信息的一个重要标准.而这些信息从哪儿来?我们不可能程序员自己一个一个去写吧?这样效率太低了! 所以,今天在这儿给大家分享一款软件.深蓝词库转换.exe工具! 下载地址是:http://download.csdn.net/detail/u011763190/8604025 希望能够帮助到大家! 还有一些比较好的词库下载地址: 百度输入法词库:http://shurufa.baidu.com/dict.html 搜狗输入法词库:http

30.IK分词器配置文件讲解以及自定义词库

主要知识点: 知道IK默认的配置文件信息 自定义词库 一.ik配置文件 ik配置文件地址:es/plugins/ik/config目录 IKAnalyzer.cfg.xml:用来配置自定义词库 main.dic:ik原生内置的中文词库,总共有27万多条,只要是这些单词,都会被分在一起 quantifier.dic:放了一些单位相关的词 suffix.dic:放了一些后缀 surname.dic:中国的姓氏 stopword.dic:英文停用词 ik原生最重要的两个配置文件 main.dic:包含

用AutoHotkey实现【小狼毫】一键添加「选中内容」到词库并重新部署

换了win10后,极点就不好用了,看上了自定义更强的小狼毫,太难掌控了,只能先用点皮毛. 目前的理解,感觉很有特色的就是能根据候选项自定义提示内容,并且还能用Ctrl-Shift-Enter上屏提示内容 比如我自定义了个词组indirect,并设置了其提示内容为Excel公式:indirect("$A$2:$E$"&COUNTA($A:$A)) 当我想输入公式时,先按↓移到第2条,再按Ctrl-Shift-Enter即可(不知道能否设置为Ctrl-Shift-2直接上屏) 回到

和我一起开发Android应用(四)——拓词算法分析和“悦词”词库解析

今天我们要部分实现背单词功能,在开始正题之前,还是附上背单词软件的下载链接:http://apk.91.com/Soft/Android/com.carlos.yueci-4.html 最近实验室有了任务,时间会紧些,因此这个项目要加快进度了. 首先把我在系列二中的功能分析拷贝过来: 功能2.背单词. 实现方法:这里要用到第二个数据库,背单词的词库.我们需要一个存放单词的TXT文件,通过解析这个TXT文件,将要背的单词解析并存进数据库中,然后根据一定的规        律弹出单词. 所用到的技术

解析搜狗词库(python)

#!/usr/bin/python # -*- coding: utf-8 -*- import struct import sys import binascii import pdb #搜狗的scel词库就是保存的文本的unicode编码,每两个字节一个字符(中文汉字或者英文字母) #找出其每部分的偏移位置即可 #主要两部分 #1.全局拼音表,貌似是所有的拼音组合,字典序 # 格式为(index,len,pinyin)的列表 # index: 两个字节的整数 代表这个拼音的索引 # len: