这篇文章,分享一个开源项目:sensitive-word 。
Github 地址:github.com/houbb/sensi…
sensitive-word 是一个功能强大的 Java 敏感词过滤框架,它不仅提供了基础的敏感词检测功能,还支持单词标签分类分级、繁简体互换、全角半角互换、汉字转拼音、模糊搜索等高级特性。
它的核心特性如下:
- 🚀 高性能: 基于 DFA 算法,匹配效率极高
- 🏷️ 标签分类: 支持敏感词分类分级管理
- 🔄 字符处理: 支持繁简体、全角半角互换
- 🎯 模糊搜索: 支持拼音、形似字等模糊匹配
- 📦 开箱即用: 简单配置即可快速集成
1 基础使用
1<dependency> 2 <groupId>com.github.houbb</groupId> 3 <artifactId>sensitive-word</artifactId> 4 <version>0.29.2</version> 5</dependency> 6
SensitiveWordHelper 作为敏感词的工具类,核心方法如下:
示例代码:
1import com.github.houbb.sensitive.word.core.SensitiveWordHelper; 2 3public class BasicExample { 4 public static void main(String[] args) { 5 String text = "这是一个包含赌博和毒品等不良内容的测试文本"; 6 // 检测是否包含敏感词 7 boolean hasSensitive = SensitiveWordHelper.contains(text); 8 System.out.println("是否包含敏感词: " + hasSensitive); 9 10 // 查找所有敏感词 11 List<String> sensitiveWords = SensitiveWordHelper.findAll(text); 12 System.out.println("发现的敏感词: " + sensitiveWords); 13 14 // 替换敏感词 15 String cleanedText = SensitiveWordHelper.replace(text); 16 System.out.println("清洗后文本: " + cleanedText); 17 18 // 使用指定字符替换 19 String customReplaced = SensitiveWordHelper.replace(text, '*'); 20 System.out.println("自定义替换: " + customReplaced); 21 } 22} 23
执行结果:
2 特殊处理
sensitive-word 为了尽可能的提升敏感词命中率,针对各种各种情况做了处理。
1、忽略大小写
1final String text = "fuCK the bad words."; 2 3String word = SensitiveWordHelper.findFirst(text); 4Assert.assertEquals("fuCK", word); 5
2、忽略圆角半角
1final String text = "fuck the bad words."; 2 3String word = SensitiveWordHelper.findFirst(text); 4Assert.assertEquals("fuck", word); 5
3、忽略数字的写法
1final String text = "这个是我的微信:9⓿二肆⁹₈③⑸⒋➃㈤㊄"; 2 3List<String> wordList = SensitiveWordBs.newInstance().enableNumCheck(true).init().findAll(text); 4Assert.assertEquals("[9⓿二肆⁹₈③⑸⒋➃㈤㊄]", wordList.toString()); 5
4、忽略繁简体
1final String text = "我爱我的祖国和五星紅旗。"; 2 3List<String> wordList = SensitiveWordHelper.findAll(text); 4Assert.assertEquals("[五星紅旗]", wordList.toString()); 5
5、忽略英文的书写格式
1final String text = "Ⓕⓤc⒦ the bad words"; 2 3List<String> wordList = SensitiveWordHelper.findAll(text); 4Assert.assertEquals("[Ⓕⓤc⒦]", wordList.toString()); 5
6、忽略重复词
1final String text = "ⒻⒻⒻfⓤuⓤ⒰cⓒ⒦ the bad words"; 2 3List<String> wordList = SensitiveWordBs.newInstance() 4 .ignoreRepeat(true) 5 .init() 6 .findAll(text); 7Assert.assertEquals("[ⒻⒻⒻfⓤuⓤ⒰cⓒ⒦]", wordList.toString()); 8
3 更多检测策略
sensitive-word 支持数字、邮箱、URL 、ipv4 多种检测策略。
示例代码:
1public class SensitiveWordQuickDemo { 2 3 public static void main(String[] args) { 4 // 邮箱检测 5 String text1 = "楼主好人,邮箱 [email protected]"; 6 List<String> emailWords = SensitiveWordBs.newInstance() 7 .enableEmailCheck(true) 8 .init() 9 .findAll(text1); 10 System.out.println("邮箱检测: " + emailWords); 11 12 // 数字检测 13 String text2 = "你懂得:12345678"; 14 List<String> numWords = SensitiveWordBs.newInstance() 15 .enableNumCheck(true) 16 .init() 17 .findAll(text2); 18 System.out.println("数字检测: " + numWords); 19 20 // URL 检测 21 String text3 = "点击链接 https://www.baidu.com 查看答案,当然也可以是 baidu.com、www.baidu.com"; 22 List<String> urlWords = SensitiveWordBs.newInstance() 23 .enableUrlCheck(true) 24 .wordCheckUrl(WordChecks.urlNoPrefix()) 25 .init() 26 .findAll(text3); 27 System.out.println("URL 检测: " + urlWords); 28 29 // IPv4 检测 30 String text4 = "个人网站,如果网址打不开可以访问 127.0.0.1。"; 31 List<String> ipWords = SensitiveWordBs.newInstance() 32 .enableIpv4Check(true) 33 .init() 34 .findAll(text4); 35 System.out.println("IPv4 检测: " + ipWords); 36 } 37 38} 39
显示结果:
4 优雅 API
为了让使用更加优雅,统一使用 fluent-api 的方式定义。
用户可以使用 SensitiveWordBs 进行如下定义:
注意:配置后,要使用我们新定义的 SensitiveWordBs 的对象,而不是以前的工具方法。工具方法配置都是默认的。
1public class AdvancedExample { 2 3 public static void main(String[] args) { 4 SensitiveWordBs wordBs = SensitiveWordBs.newInstance() 5 .ignoreCase(true) 6 .ignoreWidth(true) 7 .ignoreNumStyle(true) 8 .ignoreChineseStyle(true) 9 .ignoreEnglishStyle(true) 10 .ignoreRepeat(false) 11 .enableNumCheck(false) 12 .enableEmailCheck(false) 13 .enableUrlCheck(false) 14 .enableIpv4Check(false) 15 .enableWordCheck(true) 16 .wordFailFast(true) 17 .wordCheckNum(WordChecks.num()) 18 .wordCheckEmail(WordChecks.email()) 19 .wordCheckUrl(WordChecks.url()) 20 .wordCheckIpv4(WordChecks.ipv4()) 21 .wordCheckWord(WordChecks.word()) 22 .numCheckLen(8) 23 .wordTag(WordTags.none()) 24 .charIgnore(SensitiveWordCharIgnores.defaults()) 25 .wordResultCondition(WordResultConditions.alwaysTrue()) 26 .init(); 27 28 final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。"; 29 System.out.println(wordBs.contains(text)); 30 System.out.println(wordBs.findFirst(text)); 31 } 32 33} 34
5 定义词库
01 新增删除敏感词
初始化之后,sensitive-word 支持对单个词的新增/删除。
addWord(word)新增敏感词,支持单个词/集合removeWord(word)删除敏感词,支持单个词/集合
示例代码:
1final String text = "测试一下新增敏感词,验证一下删除和新增对不对"; 2 3SensitiveWordBs sensitiveWordBs = 4SensitiveWordBs.newInstance() 5 .wordAllow(WordAllows.empty()) 6 .wordDeny(WordDenys.empty()) 7 .init(); 8 9// 当前 10Assert.assertEquals("[]", sensitiveWordBs.findAll(text).toString()); 11 12// 新增单个 13sensitiveWordBs.addWord("测试"); 14sensitiveWordBs.addWord("新增"); 15Assert.assertEquals("[测试, 新增, 新增]", sensitiveWordBs.findAll(text).toString()); 16 17// 删除单个 18sensitiveWordBs.removeWord("新增"); 19Assert.assertEquals("[测试]", sensitiveWordBs.findAll(text).toString()); 20sensitiveWordBs.removeWord("测试"); 21Assert.assertEquals("[]", sensitiveWordBs.findAll(text).toString()); 22 23// 新增集合 24sensitiveWordBs.addWord(Arrays.asList("新增", "测试")); 25Assert.assertEquals("[测试, 新增, 新增]", sensitiveWordBs.findAll(text).toString()); 26// 删除集合 27sensitiveWordBs.removeWord(Arrays.asList("新增", "测试")); 28Assert.assertEquals("[]", sensitiveWordBs.findAll(text).toString()); 29 30// 新增数组 31sensitiveWordBs.addWord("新增", "测试"); 32Assert.assertEquals("[测试, 新增, 新增]", sensitiveWordBs.findAll(text).toString()); 33// 删除集合 34sensitiveWordBs.removeWord("新增", "测试"); 35Assert.assertEquals("[]", sensitiveWordBs.findAll(text).toString()); 36
02 自定义词库来源(数据库 / 接口)
我们可以实现接口 IWordDeny 来扩展,例如从数据库取敏感词,实现自定义词库。
1 2public class CustomDictionaryExample { 3 4 public static void main(String[] args) { 5 SensitiveWordBs wordBs = SensitiveWordBs.newInstance() 6 .wordDeny(new IWordDeny() { 7 @Override 8 public List<String> deny() { 9 // 这里可以从数据库查询 10 return Arrays.asList("勇哥", "敏感词A", "敏感词B"); 11 } 12 }) 13 .init(); 14 15 System.out.println(wordBs.findAll("这是一个敏感词A 的测试")); 16 } 17 18} 19
6 Spring 整合
当我们需要在 SpringBoot 项目中使用敏感词过滤文本时,可以定义敏感词引导类。
示例见如下代码:
1@Configuration 2public class SpringSensitiveWordConfig { 3 4 @Autowired 5 private MyDdWordAllow myDdWordAllow; 6 7 @Autowired 8 private MyDdWordDeny myDdWordDeny; 9 10 /** 11 * 初始化引导类 12 * @return 初始化引导类 13 * @since 1.0.0 14 */ 15 @Bean 16 public SensitiveWordBs sensitiveWordBs() { 17 SensitiveWordBs sensitiveWordBs = SensitiveWordBs.newInstance() 18 .wordAllow(WordAllows.chains(WordAllows.defaults(), myDdWordAllow)) 19 .wordDeny(myDdWordDeny) 20 // 各种其他配置 21 .init(); 22 23 return sensitiveWordBs; 24 } 25 26} 27
7 敏感词控制台
sensitive-word-admin 是和 sensitive-word 配套使用的控制台。
- 前端采用Vue、Element UI。
- 后端采用Spring Boot、Spring Security、Redis & Jwt。
- 权限认证使用Jwt,支持多终端认证系统。
- 支持加载动态权限菜单,多方式轻松权限控制。
- 高效率开发,使用代码生成器可以一键生成前后端代码。
参考文章:
《sensitive-word:一个简单易用的敏感词过滤框架》 是转载文章,点击查看原文。
