当前位置: 首页 > news >正文

【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.lryc.cn/news/149092.html

相关文章:

  • stable diffusion实践操作-提示词
  • leetcode8.字符串转整数-Java
  • 从零开始的Hadoop学习(四)| SSH无密登录配置、集群配置
  • 微信小程序活动报名管理系统设计与实现
  • 用Kubernetes(k8s)的ingress部署https应用
  • 【附安装包】MyEclipse2020安装教程
  • 软件与软件工程
  • 记录一下:基于nginx配置的封禁真实IP
  • 【狂神】Spring5笔记(1-9)
  • Redis——急速安装并设置自启(CentOS)
  • C++中使用while循环
  • 视频融合平台EasyCVR视频汇聚平台关于小区高空坠物安全实施应用方案设计
  • IBM安全发布《2023年数据泄露成本报告》,数据泄露成本创新高
  • python爬虫—requests
  • 应用案例 | 3D视觉引导解决方案汽车零部件上下料
  • const {}解构赋值
  • 一篇文章带你了解-selenium工作原理详解
  • H5 + C3基础(八)(3d转换 位移 旋转)
  • PyQt6 GUI界面设计和Nuitka包生成exe程序(全笔记)
  • 学习网络编程No.5【TCP套接字通信】
  • 常用的时间段的时间戳
  • 博客系统后台控制层接口编写
  • 生成 MySQL 删除索引、创建索引、分析表的 SQL 语句
  • mongodb建用户
  • 无门槛访问ChatGPT升级版-数据指北AI
  • 前端需要学习哪些技术?
  • 详解排序算法(附带Java/Python/Js源码)
  • 手写Mybatis:第8章-把反射用到出神入化
  • 基于AI智能分析网关EasyCVR视频汇聚平台关于能源行业一体化监控平台可实施应用方案
  • 《Flink学习笔记》——第四章 Flink运行时架构