【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.rhkb.cn/news/114471.html

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

相关文章

算法通关村-----哈希和队列的基本知识

哈希概念 哈希也称为散列&#xff0c;就是把任意长度的输入&#xff0c;通过散列算法&#xff0c;变成固定长度的输出&#xff0c;这个输出值就是散列值。 哈希存储 现在有1&#xff0c;2&#xff0c;3…15&#xff0c;要将其存储到大小为7的哈希表中&#xff0c;应该如何存…

OS 死锁处理

如果P先申请mutex 则mutex从1置零&#xff0c;假设申请到的empty 0则empty变成-1阻塞态 同理C中mutex从0变为-1&#xff0c;那么如果想离开阻塞态&#xff0c;那么就需要执行V&#xff08;empty&#xff09;但是如果执行V&#xff08;empty&#xff09;就需要P&#xff08;mu…

什么是跨域(cross-origin)请求,如何解决跨域问题?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 跨域请求和跨域问题⭐ 解决跨域问题的方法1. CORS&#xff08;跨域资源共享&#xff09;2. JSONP&#xff08;JSON with Padding&#xff09;3. 代理服务器4. WebSocket5. 使用服务器中继 ⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff…

python爬取bilibili,下载视频

一. 内容简介 python爬取bilibili&#xff0c;下载视频 二. 软件环境 2.1vsCode 2.2Anaconda version: conda 22.9.0 2.3代码 链接&#xff1a;https://pan.baidu.com/s/1WuXTso_iltLlnrLffi1kYQ?pwd1234 三.主要流程 3.1 下载单个视频 代码 import requests impor…

C# 多线程交替按照指定顺序执行

1.关于AutoResetEvent和ManualResetEvent的区别解释如下&#xff1a; AutoResetEvent和ManualResetEvent是.NET中的两个线程同步类。它们之间的主要区别在于其释放信号的方式以及对等待线程的影响。 AutoResetEvent的作用是在等待的线程被信号唤醒后&#xff0c;将信号自动重…

Flink CDC学习笔记

第一章 CDC简介 1.1 什么是CDC ​ CDC (Change Data Capture 变更数据获取&#xff09;的简称。核心思想就是&#xff0c;检测并获取数据库的变动&#xff08;增删查改&#xff09;&#xff0c;将这些变更按发生的顺序记录下来&#xff0c;写入到消息中间件以供其它服务进行订…

什么是Python爬虫分布式架构,可能遇到哪些问题,如何解决

目录 什么是Python爬虫分布式架构 1. 调度中心&#xff08;Scheduler&#xff09;&#xff1a; 2. 爬虫节点&#xff08;Crawler Node&#xff09;&#xff1a; 3. 数据存储&#xff08;Data Storage&#xff09;&#xff1a; 4. 反爬虫处理&#xff08;Anti-Scraping&…

OpenCV(一):Android studio jni配置OpenCV(亲测有效,保姆级)

目录 1.下载OpenCV的SDK 2.创建Android Native C项目 3.Android项目中导入OpenCV工程 4.导入OpenCV的库文件 5.实现opencv高斯模糊图像处理的demo 要在Android Studio中配置使用OpenCV库的C方法&#xff0c;需要完成以下步骤&#xff1a; 1.下载OpenCV的SDK 首先&#x…

GIT命令只会抄却不理解?看完原理才能事半功倍!

系列文章目录 手把手教你安装Git&#xff0c;萌新迈向专业的必备一步 GIT命令只会抄却不理解&#xff1f;看完原理才能事半功倍&#xff01; 系列文章目录一、Git 的特征1. 文件系统2. 分布式 二、GIT的术语1. 区域术语2. 名词术语1. 提交对象2. 分支3. HEAD4. 标签&#xff0…

【python爬虫】6.爬虫实操(带参数请求数据)

文章目录 前言项目&#xff1a;狂热粉丝分析过程什么是带参数请求数据如何带参数请求数据 代码实现被隐藏的歌曲清单什么是Request Headers如何添加Request Headers 复习 前言 先来复习一下上一关的主要知识吧&#xff0c;先热个身。 Network能够记录浏览器的所有请求。我们最…

Go:关于‘fresh‘ 不是内部或外部命令,也不是可运行的程序问题的解决方案

如果你使用了go get命令来安装fresh包&#xff0c;那么fresh命令可能没有被正确添加到系统的PATH环境变量中&#xff0c;需要修改你的fresh.exe的文件存放位置。 一般而言&#xff0c;你会将GO的安装文件夹Go与工作区文件夹GoProjects分开&#xff08;你的文件夹名称与我的不同…

Docker Compose 安装使用 教程

Docker Compose 1.1 简介 Compose 项目是 Docker 官方的开源项目&#xff0c;负责实现对 Docker 容器集群的 快速编排 。从功能上看&#xff0c;跟 OpenStack 中的 Heat 十分类似。 其代码目前在 https://github.com/docker/compose 上开源。 Compose 定位是 「定义和运行多个…

Linux音频了解

ALPHA I.MX6U 开发板支持音频&#xff0c;板上搭载了音频编解码芯片 WM8960&#xff0c;支持播放以及录音功能&#xff01; 本章将会讨论如下主题内容。 ⚫ Linux 下 ALSA 框架概述&#xff1b; ⚫ alsa-lib 库介绍&#xff1b; ⚫ alsa-lib 库移植&#xff1b; ⚫ alsa-l…

计算机网络 第二节

目录 一&#xff0c;计算机网络的分类 1.按照覆盖范围分 2.按照所属用途分 二&#xff0c;计算机网络逻辑组成部分 1.核心部分 &#xff08;通信子网&#xff09; 1.1电路交换 1.2 分组交换 两种方式的特点 重点 2.边缘部分 &#xff08;资源子网&#xff09; 进程通信的方…

如何在 iPhone 上检索已删除的短信

我厌倦了垃圾短信。当我例行公事地删除 iPhone 上的这些不需要的消息时&#xff0c;当我分散注意力时&#xff0c;我通过点击错误的按钮清除了所有消息。这些被删除的消息中包含两条团购验证信息。有什么办法可以从 iPhone 检索我的消息吗&#xff1f; 有时我们可能会不小心删…

iOS 使用coreData存贮页面的模型数据中的字典

我们使用coreData时候&#xff0c;会遇到较为复杂的数据类型的存贮&#xff0c;例如&#xff0c;我们要存一个模型&#xff0c;但是一个模型里面有个字典&#xff0c;这时候&#xff0c;我们该如何存贮呢 如图所示&#xff0c;一个对象中含有一个字典 我们实现一个公共的方法…

Python小知识 - 使用Python进行数据分析

使用Python进行数据分析 数据分析简介 数据分析&#xff0c;又称为信息分析&#xff0c;是指对数据进行综合处理、归纳提炼、概括总结的过程&#xff0c;是数据处理的第一步。 数据分析的目的是了解数据的内在规律&#xff0c;为数据挖掘&#xff0c;并应用于商业决策、科学研究…

java 批量下载将多个文件(minio中存储)压缩成一个zip包

我的需求是将minio中存储的文件按照查询条件查询出来统一压成一个zip包然后下载下来。 思路&#xff1a;针对这个需求&#xff0c;其实可以有多个思路&#xff0c;不过也大同小异&#xff0c;一般都是后端返回流文件前端再处理下载&#xff0c;也有少数是压缩成zip包之后直接给…

登录校验-Filter-登录校验过滤器

目录 思路 登录校验Filter-流程 步骤 流程图 登录校验Filter-代码 过滤器类 工具类 测试登录 登录接口功能请求 其他接口功能请求 前后端联调 思路 前端访问登录接口&#xff0c;登陆成功后&#xff0c;服务端会生成一个JWT令牌&#xff0c;并返回给前端&#xff0…