sensitive-word:一个简单易用的敏感词过滤框架

news/2025/12/14 11:29:31/文章来源:https://www.cnblogs.com/makemylife/p/19130244

这篇文章,分享一个开源项目:sensitive-word

Github 地址:https://github.com/houbb/sensitive-word

sensitive-word 是一个功能强大的 Java 敏感词过滤框架,它不仅提供了基础的敏感词检测功能,还支持单词标签分类分级、繁简体互换、全角半角互换、汉字转拼音、模糊搜索等高级特性。

它的核心特性如下:

  • 🚀 高性能: 基于 DFA 算法,匹配效率极高
  • 🏷️ 标签分类: 支持敏感词分类分级管理
  • 🔄 字符处理: 支持繁简体、全角半角互换
  • 🎯 模糊搜索: 支持拼音、形似字等模糊匹配
  • 📦 开箱即用: 简单配置即可快速集成

1 基础使用

<dependency><groupId>com.github.houbb</groupId><artifactId>sensitive-word</artifactId><version>0.29.2</version>
</dependency>

SensitiveWordHelper 作为敏感词的工具类,核心方法如下:

示例代码:

import com.github.houbb.sensitive.word.core.SensitiveWordHelper;public class BasicExample {public static void main(String[] args) {String text = "这是一个包含赌博和毒品等不良内容的测试文本";// 检测是否包含敏感词boolean hasSensitive = SensitiveWordHelper.contains(text);System.out.println("是否包含敏感词: " + hasSensitive);// 查找所有敏感词List<String> sensitiveWords = SensitiveWordHelper.findAll(text);System.out.println("发现的敏感词: " + sensitiveWords);// 替换敏感词String cleanedText = SensitiveWordHelper.replace(text);System.out.println("清洗后文本: " + cleanedText);// 使用指定字符替换String customReplaced = SensitiveWordHelper.replace(text, '*');System.out.println("自定义替换: " + customReplaced);}
}

执行结果:

2 特殊处理

sensitive-word 为了尽可能的提升敏感词命中率,针对各种各种情况做了处理。

1、忽略大小写

final String text = "fuCK the bad words.";String word = SensitiveWordHelper.findFirst(text);
Assert.assertEquals("fuCK", word);

2、忽略圆角半角

final String text = "fuck the bad words.";String word = SensitiveWordHelper.findFirst(text);
Assert.assertEquals("fuck", word);

3、忽略数字的写法

final String text = "这个是我的微信:9⓿二肆⁹₈③⑸⒋➃㈤㊄";List<String> wordList = SensitiveWordBs.newInstance().enableNumCheck(true).init().findAll(text);
Assert.assertEquals("[9⓿二肆⁹₈③⑸⒋➃㈤㊄]", wordList.toString());

4、忽略繁简体

final String text = "我爱我的祖国和五星紅旗。";List<String> wordList = SensitiveWordHelper.findAll(text);
Assert.assertEquals("[五星紅旗]", wordList.toString());

5、忽略英文的书写格式

final String text = "Ⓕⓤc⒦ the bad words";List<String> wordList = SensitiveWordHelper.findAll(text);
Assert.assertEquals("[Ⓕⓤc⒦]", wordList.toString());

6、忽略重复词

final String text = "ⒻⒻⒻfⓤuⓤ⒰cⓒ⒦ the bad words";List<String> wordList = SensitiveWordBs.newInstance().ignoreRepeat(true).init().findAll(text);
Assert.assertEquals("[ⒻⒻⒻfⓤuⓤ⒰cⓒ⒦]", wordList.toString());

3 更多检测策略

sensitive-word 支持数字、邮箱、URL 、ipv4 多种检测策略。

示例代码:

public class SensitiveWordQuickDemo {public static void main(String[] args) {// 邮箱检测String text1 = "楼主好人,邮箱 sensitiveword@xx.com";List<String> emailWords = SensitiveWordBs.newInstance().enableEmailCheck(true).init().findAll(text1);System.out.println("邮箱检测: " + emailWords);// 数字检测String text2 = "你懂得:12345678";List<String> numWords = SensitiveWordBs.newInstance().enableNumCheck(true).init().findAll(text2);System.out.println("数字检测: " + numWords);// URL 检测String text3 = "点击链接 https://www.baidu.com 查看答案,当然也可以是 baidu.com、www.baidu.com";List<String> urlWords = SensitiveWordBs.newInstance().enableUrlCheck(true).wordCheckUrl(WordChecks.urlNoPrefix()).init().findAll(text3);System.out.println("URL 检测: " + urlWords);// IPv4 检测String text4 = "个人网站,如果网址打不开可以访问 127.0.0.1。";List<String> ipWords = SensitiveWordBs.newInstance().enableIpv4Check(true).init().findAll(text4);System.out.println("IPv4 检测: " + ipWords);}}

显示结果:

4 优雅 API

为了让使用更加优雅,统一使用 fluent-api 的方式定义。

用户可以使用 SensitiveWordBs 进行如下定义:

注意:配置后,要使用我们新定义的 SensitiveWordBs 的对象,而不是以前的工具方法。工具方法配置都是默认的。

public class AdvancedExample {public static void main(String[] args) {SensitiveWordBs wordBs = SensitiveWordBs.newInstance().ignoreCase(true).ignoreWidth(true).ignoreNumStyle(true).ignoreChineseStyle(true).ignoreEnglishStyle(true).ignoreRepeat(false).enableNumCheck(false).enableEmailCheck(false).enableUrlCheck(false).enableIpv4Check(false).enableWordCheck(true).wordFailFast(true).wordCheckNum(WordChecks.num()).wordCheckEmail(WordChecks.email()).wordCheckUrl(WordChecks.url()).wordCheckIpv4(WordChecks.ipv4()).wordCheckWord(WordChecks.word()).numCheckLen(8).wordTag(WordTags.none()).charIgnore(SensitiveWordCharIgnores.defaults()).wordResultCondition(WordResultConditions.alwaysTrue()).init();final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。";System.out.println(wordBs.contains(text));System.out.println(wordBs.findFirst(text));}}

5 定义词库

01 新增删除敏感词

初始化之后,sensitive-word 支持对单个词的新增/删除。

  • addWord(word) 新增敏感词,支持单个词/集合

  • removeWord(word) 删除敏感词,支持单个词/集合

示例代码:

final String text = "测试一下新增敏感词,验证一下删除和新增对不对";SensitiveWordBs sensitiveWordBs =
SensitiveWordBs.newInstance().wordAllow(WordAllows.empty()).wordDeny(WordDenys.empty()).init();// 当前
Assert.assertEquals("[]", sensitiveWordBs.findAll(text).toString());// 新增单个
sensitiveWordBs.addWord("测试");
sensitiveWordBs.addWord("新增");
Assert.assertEquals("[测试, 新增, 新增]", sensitiveWordBs.findAll(text).toString());// 删除单个
sensitiveWordBs.removeWord("新增");
Assert.assertEquals("[测试]", sensitiveWordBs.findAll(text).toString());
sensitiveWordBs.removeWord("测试");
Assert.assertEquals("[]", sensitiveWordBs.findAll(text).toString());// 新增集合
sensitiveWordBs.addWord(Arrays.asList("新增", "测试"));
Assert.assertEquals("[测试, 新增, 新增]", sensitiveWordBs.findAll(text).toString());
// 删除集合
sensitiveWordBs.removeWord(Arrays.asList("新增", "测试"));
Assert.assertEquals("[]", sensitiveWordBs.findAll(text).toString());// 新增数组
sensitiveWordBs.addWord("新增", "测试");
Assert.assertEquals("[测试, 新增, 新增]", sensitiveWordBs.findAll(text).toString());
// 删除集合
sensitiveWordBs.removeWord("新增", "测试");
Assert.assertEquals("[]", sensitiveWordBs.findAll(text).toString());

02 自定义词库来源(数据库 / 接口)

我们可以实现接口 IWordDeny 来扩展,例如从数据库取敏感词,实现自定义词库。

public class CustomDictionaryExample {public static void main(String[] args) {SensitiveWordBs wordBs = SensitiveWordBs.newInstance().wordDeny(new IWordDeny() {@Overridepublic List<String> deny() {// 这里可以从数据库查询return Arrays.asList("勇哥", "敏感词A", "敏感词B");}}).init();System.out.println(wordBs.findAll("这是一个敏感词A 的测试"));}}

6 Spring 整合

当我们需要在 SpringBoot 项目中使用敏感词过滤文本时,可以定义敏感词引导类。

示例见如下代码:

@Configuration
public class SpringSensitiveWordConfig {@Autowiredprivate MyDdWordAllow myDdWordAllow;@Autowiredprivate MyDdWordDeny myDdWordDeny;/*** 初始化引导类* @return 初始化引导类* @since 1.0.0*/@Beanpublic SensitiveWordBs sensitiveWordBs() {SensitiveWordBs sensitiveWordBs = SensitiveWordBs.newInstance().wordAllow(WordAllows.chains(WordAllows.defaults(), myDdWordAllow)).wordDeny(myDdWordDeny)// 各种其他配置.init();return sensitiveWordBs;}}

7 敏感词控制台

sensitive-word-admin 是和 sensitive-word 配套使用的控制台。

  • 前端采用Vue、Element UI。
  • 后端采用Spring Boot、Spring Security、Redis & Jwt。
  • 权限认证使用Jwt,支持多终端认证系统。
  • 支持加载动态权限菜单,多方式轻松权限控制。
  • 高效率开发,使用代码生成器可以一键生成前后端代码。

参考文章:

https://cloud.tencent.com/developer/news/1311331

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

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

相关文章

如何使用 ManySpeech 调用 SenseVoiceSmall 模型

一、模型与组件简介SenseVoice 模型多语言音频理解开源模型,支持语音识别、语种识别、情感识别等功能,适用于中、粤、英、日、韩等语言。 ManySpeech.AliParaformerAsrC# 语音识别推理库,支持 paraformer-large、pa…

国庆假期总结

🎉国庆总览🎉 学习🎯被学习充满的假期真是太充实(无聊)了机器学习。学习了吴恩达的机器学习,看了一百多集,实践做了小部分,我感觉到只学习到了皮毛,难的。其实只是选修课而已在这个学期,但是我想这是专业…

2025浇注型聚氨酯厂家最新推荐榜:聚氨酯胶黏剂/聚氨酯胶辊/聚氨酯制品/聚氨酯原料/液体聚氨酯/聚氨酯浇注料/聚氨酯ABC料/浇筑聚氨酯/聚氨酯预聚物全场景实力厂家

在当今工业材料领域,浇注型聚氨酯作为一种高性能弹性体材料,因其优异的耐磨性、耐油性和机械强度,在机械制造、矿山设备、印刷包装等行业得到广泛应用。随着市场需求持续增长,如何从众多厂家中筛选出优质供应商成为…

动态张量运算自动优化技术解析

本文介绍了一种名为DietCode的新型自动调度器,能够高效处理动态形状的张量运算,将优化过程加速6倍以上,同时使生成代码性能提升高达70%,显著提升机器学习工作效率。自动优化动态张量运算的执行 深度学习模型核心依…

多线程插入也是随机io,那为啥不用uuid

多线程插入也是随机io,那为啥不用uuid首先,并发写入确实是随机io,但是uuid带来的页分裂更恶劣 而多线程并发写入有序id,操作系统有办法优化老实说ds说的有点牵强

[论文阅读]PPT: Backdoor Attacks on Pre-trained Models via Poisoned Prompt Tuning - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

10. 模型与视图

一、模型与视图模型/视图架构包含三部分:模型(Model)是应用对象,用来表示数据;视图(View)是模型的用户界面,用来显示数据;委托(Delegate,也被称为 代理)可以定制数据的渲染和编辑方式。通过数据和界面进行…

[KaibaMath]1004 关于f(x,y) = [x]+[y] - [x+y]的平移稳定性

[KaibaMath]1004 关于f(x,y) = [x]+[y] - [x+y]的平移稳定性令f(x,y) = [x]+[y] - [x+y], g(x, y) = {x} + {y} - {x+y},则f(x, y) + g(x, y)= 0。 注意f(x, y)和g(x, y)均具有平移稳定性。 例如:f(x+M, y+N) = f(x,…

2025.10 国庆集训模拟赛总结

把门视为点,找环,答案就是环的长度先预处理前缀和 然后预处理f[i]表示满足j<i且aj==ai的最大的j。 答案就变成了:第一问用树套树类结构维护 第二问直接二分第一问就行,因为第一问我们在先做了。 树套树太难写,…

Easysearch 字段隐身之谜:source_reuse 与 ignore_above 的陷阱解析

背景问题 前阵子,社区有小伙伴在使用 Easysearch 的数据压缩功能时发现,在开启 source_reuse 和 ZSTD 后,一个字段的内容看不到了。 索引的设置如下: {......"settings": {"index": {"co…

TortoiseSVN账号切换 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Exchange安全漏洞分析:ProxyOracle攻击链详解

本文深入分析Microsoft Exchange中的ProxyOracle攻击链,包含CVE-2021-31195 XSS漏洞和CVE-2021-31196填充Oracle攻击,攻击者可通过恶意链接获取用户明文密码,涉及FBA认证机制和加密cookie解析过程。Orange:MS Exch…

牛客 周赛111 20251008

牛客 周赛111 20251009 https://ac.nowcoder.com/acm/contest/117763 A: 题目大意: void solve(){int a, b, c;cin >> a >> b >> c;if (b != a + 1 || c != b + 1) cout << "No";…

防抖 解释

防抖: 核心就是当一个现象停止一段时间后, 才执行动作. 而不是每次都执行.主意timer的配置

从零到一搭建:vue3+vite7+antfu+stylelint+githooks,全流程配置,附带源码,集成css变量使用,下载即用

@目录0 基础环境0.1 node版本0.2 包管理器0.3 vscode插件1 创建项目——vue官网方式1.1 创建命令1.2 初始化git2 语法检查:antfu组合eslint和prettier2.1 安装命令2.2 安装依赖2.3 在package.json中添加脚本2.4 修改e…

晶台光耦在手机PD快充上的应用 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

bat批处理脚本文件-获取当前时间的几种方法

前言全局说明获取当前时间的几种方法一、说明 1.1 环境: Windows 7 旗舰版二、方法一 2.1 源码 @echo off@REM 获取当前时间 https://www.cnblogs.com/wutou/p/19130116 SET year=%date:~0,4% SET month=%date:~5,2% S…

二分图最大权完美匹配 KM算法

#include<iostream> #include<cstdio> #include<cmath> #include<cstring> using namespace std; #define LL long long #define N 510 #define INF 1e12 int n,m; int match[N];//右点匹配了…

IDM弹窗解决 - -一叶知秋

IDM弹窗解决1、打开任务管理器,结束IDM任务(一定要结束全部的IDM任务)2、在控制面板中,打开 管理工具(有搜索)3、然后打开 本地安全策略4、找到 软件限制策略->其它规则,如果 软件限制策略 下面没有选项,就…

PHP+MySQL开发语言 在线下单订水送水小脚本源码及搭建指南

PHP+MySQL开发语言 在线下单订水送水小脚本源码及搭建指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consola…