敏感词过滤器的实现

敏感词过滤器的实现敏感词过滤器的实现导包敏感词文件前缀树的实现敏感词过滤器的实现导包本文的敏感词过滤器用在SpringBoot项目中,因此,首先需要在pom.xml文件中导入如下依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId></dependency><depend

大家好,又见面了,我是你们的朋友全栈君。

导包

本文的敏感词过滤器用在SpringBoot项目中,因此,首先需要在pom.xml文件中导入如下依赖

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-devtools</artifactId>
		<scope>runtime</scope>
</dependency>

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
</dependency>

<dependency>
		<groupId>org.apache.commons</groupId>
		<artifactId>commons-lang3</artifactId>
		<version>3.9</version>
</dependency>

敏感词文件

在resources目录下,创建sensitive-word.txt,里面填入需要过滤的敏感词信息。
在这里插入图片描述
在这里插入图片描述

前缀树的实现

前缀树TrieNode以一个空节点为头结点,每个节点下包含若干子节点,不同节点代表不同字符。TrieNode 由两部分组成,首先是一个boolean变量,表示该结点是否为一个关键词的终结点。其次是该结点的子节点集合,在本文中,用HashMap存储子节点,key存储结点代表的字符,类型为Character,value为TrieNode,表示子节点。实现的代码如下。

    //前缀树
    private class TrieNode{ 
   
        //关键词结束标识
        private boolean isKeywordEnd = false;

        //子节点
        private Map<Character,TrieNode> subNodes = new HashMap<>();
		
		//isKeywordEnd的get、set方法
        public boolean isKeywordEnd() { 
   
            return isKeywordEnd;
        }

        public void setKeywordEnd(boolean keywordEnd) { 
   
            isKeywordEnd = keywordEnd;
        }

        //添加子节点
        public void addSubNode(Character c,TrieNode node){ 
   
            subNodes.put(c,node);
        }

        //获取子节点
        public TrieNode getSubNode(Character c){ 
   
            return subNodes.get(c);
        }
    }

敏感词过滤器的实现

@Component
public class SensitiveFilter { 
   
    // 替换符
    private static final String REPLACEMENT = "***";

    //根节点
    private TrieNode rootNode = new TrieNode();

    //bean的初始化方法,服务一启动,容器自动给bean执行此方法完成初始化
    //此方法的目的是读取敏感词文件,构建敏感词前缀树
    @PostConstruct
    public void init(){ 
   
        try(
                InputStream is = this.getClass().getClassLoader().getResourceAsStream("sensitive-words.txt");
                BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                ){ 
   
            String keyword;
            while((keyword=reader.readLine())!=null){ 
   
                this.addKeyword(keyword);
            }
        }catch (IOException e){ 
   
            logger.error("加载敏感词文件失败: " + e.getMessage());
        }
    }
    
    //将一个敏感词添加到前缀树
    private void addKeyword(String keyword){ 
   
        TrieNode tempNode = rootNode;
        for (int i = 0; i <keyword.length() ; i++) { 
   
            char c = keyword.charAt(i);
            TrieNode subNode = tempNode.getSubNode(c);
            if(subNode==null){ 
   
                //初始化子节点
                subNode = new TrieNode();
                tempNode.addSubNode(c,subNode);
            }
            //指向子节点,进入下一轮循环
            tempNode = subNode;

            //设置结束标志
            if(i==keyword.length()-1){ 
   
                tempNode.setKeywordEnd(true);
            }
        }
    }


    /** * 过滤敏感词 * * @param text 待过滤的文本 * @return 过滤后的文本 */
    public String filter(String text){ 
   
        if(StringUtils.isBlank(text)){ 
   
            return null;
        }
        //指针1
        TrieNode tempNode = rootNode;
        //指针2
        int begin = 0;
        //指针3
        int position = 0;
        //结果
        StringBuilder sb = new StringBuilder();
        while(position<text.length()){ 
   
            char c = text.charAt(position);
            /* 跳过符号 情况一:符号在敏感词前面,将符号写入结果,如 ☆敏感词 情况二:符号在敏感词中间,则将符号与敏感词一起替换,如敏☆感☆词 */
            if(isSymbol(c)){ 
   
                //若指针1处于根节点,对应情况一,将符号计入结果,让指针2向下走一步
                if(tempNode==rootNode){ 
   
                    sb.append(c);
                    begin++;
                }
                //无论符号在开头还是敏感词中间,指针3都向下走一步
                position++;
                continue;
            }
            //检查下级节点
            tempNode = tempNode.getSubNode(c);
            if(tempNode==null){ 
   
                //以begin开头的的字符串不是敏感词
                sb.append(text.charAt(begin));
                //指针2和指针3共同指向指针2的下一个位置
                position = ++begin;
                //指针1重新指向根节点
                tempNode = rootNode;
            }else if(tempNode.isKeywordEnd()){ 
   
                //发现敏感词,将begin~position字符串替换
                sb.append(REPLACEMENT);
                //进入下一个位置
                begin = ++position;
                //指针1重新指向根节点
                tempNode = rootNode;
            }else { 
   
                //检查下一个字符
                position++;
            }
        }
        //将最后一批字符计入结果
        sb.append(text.substring(begin));
        return sb.toString();
    }
    //判断是否为符号
    private boolean isSymbol(Character c){ 
   
        // 0x2E80~0x9FFF 是东亚文字范围
        return !CharUtils.isAsciiAlphanumeric(c) && (c < 0x2E80 || c > 0x9FFF);
    }
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/132243.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ccd视觉定位教程_正规CCD视觉定位系统工作原理[通俗易懂]

    ccd视觉定位教程_正规CCD视觉定位系统工作原理[通俗易懂]产品品牌CCD视觉定位系统发货城市-有效期至长期有效最小起订1产品单价面议深圳精科视觉科技有限公司成立于2011年底,是一家在视觉及自动化领域有着多年经验的科技公司,专业从事非标自动化机器视觉整套解决方案。公司集研发、销售、维护为一体,汇聚了一批追求卓越、勇于探索、敢于创新、在行业内具有丰富经验的工程技术人员,组建了一支专业、敬业的市场营销团队。激光打标技术具有以下的特点1、可对绝大多数金属或非金…

    2022年6月16日
    53
  • fastjson的JSONArray和JSONObject[通俗易懂]

    fastjson的JSONArray和JSONObject[通俗易懂]什么是JSON?JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于javascriptProgrammingLanguage,StandardECMA-2623rdEdition-December1999的一个子集。JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言

    2022年6月7日
    56
  • ghost备份系统有什么用_win备份和ghost备份的区别

    ghost备份系统有什么用_win备份和ghost备份的区别  Ghost(是GeneralHardwareOrientedSoftwareTransfer的缩写译为“面向通用型硬件系统传送器”)软件是美国赛门铁克公司推出的一款出色的硬盘备份还原工具,可以实现FAT16、FAT32、NTFS、OS2等多种硬盘分区格式的分区及硬盘的备份还原。俗称克隆软件。  1、特点:既然称之为克隆软件,说明其Ghost的备份还原是以硬盘的扇区为单位进行的

    2025年9月16日
    6
  • git已经提交的文件回复忽略「建议收藏」

    git已经提交的文件回复忽略「建议收藏」将文件加入到忽略文件中使用命令,已提交的文件如何恢复忽略git rm –cached 文件git rm –cached -r 文件夹git rm –cached .push到远程

    2022年8月8日
    4
  • 5G接入网与基站演进

    5G接入网与基站演进5G 基站重组 AAU 有源天线单元 ActiveAntenn RRU 有源射频 无源天线 BBU 的部分物理层功能 DU 分布式单元 由 BBU 中部分物理层和实时服务的功能所分割而成 由于对时延要求极高 DU 需与 AAU 就近部署 1ms 以内 一个 DU 可连接多个 AAU CU 中央单元 BBU 中非实时的功能分割而出 CU 可采用云化部署方式 支持核心网 UPF 下沉与边缘计算融合部署 一个 CU 可管理一个或多个 DU 减少前传带宽和时延 5G 基站前传 AAU 和 DU 之间 带宽高达数百 G 至 Tbps 传

    2025年11月29日
    3
  • javaWeb前后台交互(二)[通俗易懂]

    javaWeb前后台交互(二)[通俗易懂]接上一篇javaWeb前后台交互。链接:https://blog.csdn.net/blackplus28/article/details/80603863一、MVC思想责任分离思想.M:Model,数据模型对象.(JavaBean)V:View,视图界面.(JSP,Panel,Window)C:Controller,控制器(Servlet)本次代码采用:Tomc…

    2022年6月13日
    27

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号