博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
过滤敏感词算法
阅读量:4044 次
发布时间:2019-05-24

本文共 4873 字,大约阅读时间需要 16 分钟。

项目中有时候会遇到将某些词进行处理或者隐藏之后的需求。利用如下算法实现简单过滤敏感词效果。

设计思路:

1,将敏感词设计成树状结构,如lzz,ha等都是敏感词,在敏感词最后加一个小星星作为结尾标志。

2,定义三个指针,指针1从树的根节点开始扫描,指针2与指针3从待处理字符串开始扫描。

3,指针3位置数据与指针1子节点数据一致,指针3后移一位,指针1移到该子节点。直到遇到小星星。

package com.zhou.wenda.service;import org.apache.commons.lang.CharUtils;import org.apache.commons.lang.StringUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.InitializingBean;import org.springframework.stereotype.Service;import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.util.HashMap;import java.util.Map;/** * @author liangzhenzhou * @create 2018-11-07 22:38 */@Servicepublic class SensitiveService implements InitializingBean{    private static final Logger logger = LoggerFactory.getLogger(SensitiveService.class);    /**     * 默认敏感词替换符     */    private static final String DEFAULT_REPLACEMENT = "****";    private class TrieNode {        /**         * true 关键词的终结 ; false 继续         */        private boolean end = false;        /**         * key下一个字符,value是对应的节点         */        private Map
subNodes = new HashMap<>(); /** * 向指定位置添加节点树 */ void addSubNode(Character key, TrieNode node) { subNodes.put(key, node); } /** * 获取下个节点 */ TrieNode getSubNode(Character key) { return subNodes.get(key); } boolean isKeywordEnd() { return end; } void setKeywordEnd(boolean end) { this.end = end; } public int getSubNodeCount() { return subNodes.size(); } } /** * 根节点 */ private TrieNode rootNode = new TrieNode(); /** * 判断是否是一个符号 */ private boolean isSymbol(char c) { int ic = (int) c; // 0x2E80-0x9FFF 东亚文字范围 return !CharUtils.isAsciiAlphanumeric(c) && (ic < 0x2E80 || ic > 0x9FFF); } /** * 过滤敏感词 */ public String filter(String text) { if (StringUtils.isBlank(text)) { return text; } String replacement = DEFAULT_REPLACEMENT; StringBuilder result = new StringBuilder(); TrieNode tempNode = rootNode; int begin = 0; // 回滚数 int position = 0; // 当前比较的位置 while (position < text.length()) { char c = text.charAt(position); // 空格直接跳过 if (isSymbol(c)) { if (tempNode == rootNode) { result.append(c); ++begin; } ++position; continue; } tempNode = tempNode.getSubNode(c); // 当前位置的匹配结束 if (tempNode == null) { // 以begin开始的字符串不存在敏感词 result.append(text.charAt(begin)); // 跳到下一个字符开始测试 position = begin + 1; begin = position; // 回到树初始节点 tempNode = rootNode; } else if (tempNode.isKeywordEnd()) { // 发现敏感词, 从begin到position的位置用replacement替换掉 result.append(replacement); position = position + 1; begin = position; tempNode = rootNode; } else { ++position; } } result.append(text.substring(begin)); return result.toString(); } private void addWord(String lineTxt) { TrieNode tempNode = rootNode; // 循环每个字节 for (int i = 0; i < lineTxt.length(); ++i) { Character c = lineTxt.charAt(i); // 过滤空格 if (isSymbol(c)) { continue; } TrieNode node = tempNode.getSubNode(c); if (node == null) { // 没初始化 node = new TrieNode(); tempNode.addSubNode(c, node); } tempNode = node; if (i == lineTxt.length() - 1) { // 关键词结束, 设置结束标志 tempNode.setKeywordEnd(true); } } } @Override public void afterPropertiesSet() throws Exception { rootNode = new TrieNode(); try { InputStream is = Thread.currentThread().getContextClassLoader() .getResourceAsStream("SensitiveWords.txt"); InputStreamReader read = new InputStreamReader(is); BufferedReader bufferedReader = new BufferedReader(read); String lineTxt; while ((lineTxt = bufferedReader.readLine()) != null) { lineTxt = lineTxt.trim(); addWord(lineTxt); } read.close(); } catch (Exception e) { logger.error("读取敏感词文件失败" + e.getMessage()); } } public static void main(String[] argv) { SensitiveService s = new SensitiveService(); s.addWord("色情"); s.addWord("好色"); System.out.print(s.filter("你好X色**情XX")); }}

 

转载地址:http://wpwci.baihongyu.com/

你可能感兴趣的文章
coursesa课程 Python 3 programming The while Statement
查看>>
course_2_assessment_6
查看>>
coursesa课程 Python 3 programming course_2_assessment_7 多参数函数练习题
查看>>
coursesa课程 Python 3 programming course_2_assessment_8 sorted练习题
查看>>
在unity中建立最小的shader(Minimal Shader)
查看>>
1.3 Debugging of Shaders (调试着色器)
查看>>
关于phpcms中模块_tag.class.php中的pc_tag()方法的含义
查看>>
vsftp 配置具有匿名登录也有系统用户登录,系统用户有管理权限,匿名只有下载权限。
查看>>
linux安装usb wifi接收器
查看>>
多线程使用随机函数需要注意的一点
查看>>
getpeername,getsockname
查看>>
让我做你的下一行Code
查看>>
浅析:setsockopt()改善程序的健壮性
查看>>
关于对象赋值及返回临时对象过程中的构造与析构
查看>>
VS 2005 CRT函数的安全性增强版本
查看>>
SQL 多表联合查询
查看>>
Visual Studio 2010:C++0x新特性
查看>>
drwtsn32.exe和adplus.vbs进行dump文件抓取
查看>>
cppcheck c++静态代码检查
查看>>
在C++中使用Lua
查看>>