【Java Web】敏感词过滤

一、前缀树

假设有敏感词:b,abc,abd,bcd,abcd,efg,hii
那么前缀树可以构造为:
在这里插入图片描述

二、敏感词过滤器

package com.nowcoder.community.util;import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@Componentpublic class SensitiveFilter {private static final Logger logger = LoggerFactory.getLogger(SensitiveFilter.class);// 敏感词替换private static final String REPLACEMENT = "***";// 初始化根节点private TrieNode rootNode = new TrieNode();// 实例被创建后自动完成敏感词库的加载和前缀树的构建@PostConstructpublic void init(){try (InputStream is = this.getClass().getClassLoader().getResourceAsStream("sensitive-words.txt");  // 通过类加载器获取敏感词库的字节流// 字节流转换为字符流// 然后在转换为具有缓冲区、读取性能高的BufferedReaderBufferedReader reader = new BufferedReader(new InputStreamReader(is));){String keyword;while((keyword=reader.readLine())!=null){ // 每读一行获取一个keywords// 添加到前缀树this.addKeyword(keyword);}} catch (IOException e) {logger.error("加载敏感词汇表失败:"+e.getMessage());throw new RuntimeException(e);}}// 将一个敏感词加入前缀树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();// 用指针2做循环while(begin < text.length()){if(position < text.length()){Character c = text.charAt(position);// 跳过符号if(isSymbol(c)){if(tempNode == rootNode){begin ++;sb.append(c);}position++;continue;}// 检查下级节点tempNode = tempNode.getSubNode(c);if(tempNode == null){ // 不是敏感词sb.append(text.charAt(begin));position = ++begin;tempNode = rootNode;} else if (tempNode.isKeywordEnd() ) { // 是敏感词sb.append(REPLACEMENT);begin = ++position;} else {position++;}} else { // position遍历出界sb.append(text.charAt(begin));position = ++begin;tempNode = rootNode;}}return sb.toString();}// 判断是否为符号private boolean isSymbol(Character c){// 0x2E80~0x9FF为东亚文字范围// CharUtils.isAsciiAlphanumeric()判断是否为普通字符return !CharUtils.isAsciiAlphanumeric(c)  && (c < 0x2E80 || c > 0x9FFF);}// 前缀树private class TrieNode{// 关键词结束标识private boolean isKeywordEnd = false;// 子节点(key是下级节点字符,value是下级节点)private Map<Character,TrieNode> subNodes = new HashMap<>();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);}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/90927.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Lua基础知识

文章目录 1. Lua简介1.1 设计目的&#xff1a;1.2 特性1.3 应用场景 2. Lua脚本学习2.1 安装2.2 lua操作2.3 lua案例 学习lua主要是为了后续做高性能缓存架构所准备的基础技术。可以先了解下基础&#xff0c;在实际使用时&#xff0c;再查缺补漏。 1. Lua简介 Lua 是一种轻量小…

Leetcode.100 相同的树

给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 代码如下&#xff1a;…

二分查找逻辑

目录 二分查找 查找逻辑 题目练习 题目描述 代码示例 总结 二分查找 二分查找是我们经常使用的一种算法&#xff0c;他的逻辑是 在升序或者降序且无重复元素的数组中&#xff0c;比较目标值和数组中间值的方法&#xff0c;每次缩小一半的搜索范围&#xff0c;相比遍历可…

.NET 操作 TDengine .NET ORM

TDengine 是国内比较流的时序库之一&#xff0c;支持群集并且免费&#xff0c;在.NET中资料比较少&#xff0c;这篇文章主要介绍SqlSugar ORM来操作TDengine 优点&#xff1a; 1、SqlSugar支持ADO.NET操作来实现TDengine&#xff0c;并且支持了常用的时间函数、支持联表、分…

Elasticsearch终端命令行用法大全

API作用使用场景curl localhost:9200/_cluster/health?pretty查看ES健康状态curl localhost:9200/_cluster/settings?pretty查看ES集群的设置其中persistent为永久设置&#xff0c;重启仍然有效&#xff1b;trainsient为临时设置&#xff0c;重启失效curl localhost:9200/_ca…

<C++> STL_list

1.list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向 其前一个元素和后一个元素。list与…

0201hdfs集群部署-hadoop-大数据学习

文章目录 1 前言2 集群规划3 hadoop安装包上传与安装3.1 上传解压 4 hadoop配置5 从节点同步和环境变量配置6 创建用户7 集群启动8 问题集8.1 Invalid URI for NameNode address (check fs.defaultFS): file:/// has no authority. 结语 1 前言 下面我们配置下单namenode节点h…

ssm+vue人力资源管理系统源码和论文

ssmvue人力资源管理系统源码和论文098 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 系统目标 本系统主要目标是对大中型公司所设计&#xff0c;是对人力资源的科学化的管理&#xff0c;使信息存储达到精确…

Spring Authorization Server入门 (十六) Spring Cloud Gateway对接认证服务

前言 之前虽然单独讲过Security Client和Resource Server的对接&#xff0c;但是都是基于Spring webmvc的&#xff0c;Gateway这种非阻塞式的网关是基于webflux的&#xff0c;对于集成Security相关内容略有不同&#xff0c;且涉及到代理其它微服务&#xff0c;所以会稍微比较麻…

PlantUML文本绘制类图

记录下文本绘制类图的语法 参考 https://juejin.cn/post/6844903731293585421 类的UML表示 使用UML表示一个类&#xff0c;主要由三部分组成。类名、属性、方法。其中属性和方法的访问修饰符用 - 、# 、 表示 private、protected、public。 如图所示&#xff0c;表示A类有一个…

htmx-使HTML更强大

‍本文作者是360奇舞团开发工程师 htmx 让我们先来看一段俳句: javascript fatigue: longing for a hypertext already in hand 这个俳句很有意思&#xff0c;是开源项目htmx文档中写的&#xff0c;意思是说&#xff0c;我们已经有了超文本&#xff0c;为什么还要去使用javascr…

基于JavaWeb和mysql实现网上书城前后端管理系统(源码+数据库+开题报告+论文+答辩技巧+项目功能文档说明+项目运行指导)

一、项目简介 本项目是一套基于JavaWeb和mysql实现网上书城前后端管理系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都…