这篇文章,分享一个开源项目: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