极简版Java敏感词检测SDK

news/2024/10/22 2:01:32/

敏感词工具

sensitive-word 基于 DFA 算法实现的高性能敏感词工具,开源在GitHub:https://github.com/houbb/sensitive-word。用于敏感词/违禁词/违法词/脏词等的识别和阻拦,是基于 DFA 算法实现的高性能 java 敏感词过滤工具框架。

使用场景:但凡是允许用户能将内容发布到网上的,任何地方理论上都应该要有一次内容审核,审核目的只要是否有违规违禁词等。之前开发过一款小程序,小程序的内容也有严格内容审核机制,当时采用的是小程序的API做的内容审核。而这款敏感词检测sdk,更加适合自己做内容平台开发等场景。

Maven引入

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

快速使用

直接判断是否包含敏感词

final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。";
Assert.assertTrue(SensitiveWordHelper.contains(text));

核心方法

在这里插入图片描述

返回第一个敏感词

final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。";String word = SensitiveWordHelper.findFirst(text);
Assert.assertEquals("五星红旗", word);

返回所有敏感词

final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。";List<String> wordList = SensitiveWordHelper.findAll(text);
Assert.assertEquals("[五星红旗, 毛主席, 天安门]", wordList.toString());

默认的替换策略

final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。";
String result = SensitiveWordHelper.replace(text);
Assert.assertEquals("****迎风飘扬,***的画像屹立在***前。", result);

指定替换的内容

final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。";
String result = SensitiveWordHelper.replace(text, '0');
Assert.assertEquals("0000迎风飘扬,000的画像屹立在000前。", result);

高级用法

自定义替换策略

场景说明:不同的敏感词有不同的替换结果。比如【游戏】替换为【电子竞技】,【失业】替换为【灵活就业】。

/*** 自定替换策略* @since 0.2.0*/
@Test
public void defineReplaceTest() {final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。";ISensitiveWordReplace replace = new MySensitiveWordReplace();String result = SensitiveWordHelper.replace(text, replace);Assert.assertEquals("国家旗帜迎风飘扬,教员的画像屹立在***前。", result);
}public class MyWordReplace implements IWordReplace {@Overridepublic void replace(StringBuilder stringBuilder, final char[] rawChars, IWordResult wordResult, IWordContext wordContext) {String sensitiveWord = InnerWordCharUtils.getString(rawChars, wordResult);// 自定义不同的敏感词替换策略,可以从数据库等地方读取if("五星红旗".equals(sensitiveWord)) {stringBuilder.append("国家旗帜");} else if("毛主席".equals(sensitiveWord)) {stringBuilder.append("教员");} else {// 其他默认使用 * 代替int wordLength = wordResult.endIndex() - wordResult.startIndex();for(int i = 0; i < wordLength; i++) {stringBuilder.append('*');}}}}

使用实例

场景1:基本使用

final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。";List<String> wordList = SensitiveWordHelper.findAll(text);
Assert.assertEquals("[五星红旗, 毛主席, 天安门]", wordList.toString());
List<String> wordList2 = SensitiveWordHelper.findAll(text, WordResultHandlers.word());
Assert.assertEquals("[五星红旗, 毛主席, 天安门]", wordList2.toString());List<IWordResult> wordList3 = SensitiveWordHelper.findAll(text, WordResultHandlers.raw());
Assert.assertEquals("[WordResult{startIndex=0, endIndex=4}, WordResult{startIndex=9, endIndex=12}, WordResult{startIndex=18, endIndex=21}]", wordList3.toString());

场景2: wordTags例子

在 dict_tag_test.txt 文件中指定对应词的标签信息。

final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。";// 默认敏感词标签为空
List<WordTagsDto> wordList1 = SensitiveWordHelper.findAll(text, WordResultHandlers.wordTags());
Assert.assertEquals("[WordTagsDto{word='五星红旗', tags=[]}, WordTagsDto{word='毛主席', tags=[]}, WordTagsDto{word='天安门', tags=[]}]", wordList1.toString());List<WordTagsDto> wordList2 = SensitiveWordBs.newInstance().wordTag(WordTags.file("dict_tag_test.txt")).init().findAll(text, WordResultHandlers.wordTags());
Assert.assertEquals("[WordTagsDto{word='五星红旗', tags=[政治, 国家]}, WordTagsDto{word='毛主席', tags=[政治, 伟人, 国家]}, WordTagsDto{word='天安门', tags=[政治, 国家, 地址]}]", wordList2.toString());

其他特性

忽略大小写

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

忽略半角圆角

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

忽略数字的写法

这里实现了数字常见形式的转换。

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

忽略繁简体

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

忽略英文的书写格式

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

忽略重复词

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());

更多策略检测

邮箱检测

邮箱等个人信息,默认未启用。

final String text = "楼主好人,邮箱 sensitiveword@xx.com";
List<String> wordList = SensitiveWordBs.newInstance().enableEmailCheck(true).init().findAll(text);
Assert.assertEquals("[sensitiveword@xx.com]", wordList.toString());

连续数字检测

一般用于过滤手机号/QQ等广告信息,默认未启用。
V0.2.1 之后,支持通过 numCheckLen(长度) 自定义检测的长度。

final String text = "你懂得:12345678";// 默认检测 8 位
List<String> wordList = SensitiveWordBs.newInstance()
.enableNumCheck(true)
.init().findAll(text);
Assert.assertEquals("[12345678]", wordList.toString());// 指定数字的长度,避免误杀
List<String> wordList2 = SensitiveWordBs.newInstance()
.enableNumCheck(true)
.numCheckLen(9)
.init()
.findAll(text);
Assert.assertEquals("[]", wordList2.toString());

网址检测

用于过滤常见的网址信息,默认未启用。

final String text = "点击链接 https://www.baidu.com 查看答案";
final SensitiveWordBs sensitiveWordBs = SensitiveWordBs.newInstance().enableUrlCheck(true).init();
List<String> wordList = sensitiveWordBs.findAll(text);
Assert.assertEquals("[https://www.baidu.com]", wordList.toString());
Assert.assertEquals("点击链接 ********************* 查看答案", sensitiveWordBs.replace(text));

IPV4 检测

避免用户通过 ip 绕过网址检测等,默认未启用。

final String text = "个人网站,如果网址打不开可以访问 127.0.0.1。";
final SensitiveWordBs sensitiveWordBs = SensitiveWordBs.newInstance().enableIpv4Check(true).init();
List<String> wordList = sensitiveWordBs.findAll(text);
Assert.assertEquals("[127.0.0.1]", wordList.toString());

引导类特性配置

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

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

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).numCheckLen(8).wordTag(WordTags.none()).charIgnore(SensitiveWordCharIgnores.defaults()).wordResultCondition(WordResultConditions.alwaysTrue()).init();final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。";
Assert.assertTrue(wordBs.contains(text));

配置说明:
在这里插入图片描述

总结

更多内容,比如如何自定因黑白名单以及敏感词标签设置等,参考官方文档:https://github.com/houbb/sensitive-word


http://www.ppmy.cn/news/1540946.html

相关文章

Meta因称其AI模型Llama为“开源” 遭炮轰,被指“污染” 开源术语

最近&#xff0c;Meta 公司因将其人工智能模型称为 “开源” 而遭到了猛烈的批评。这一指控来自于开源倡导组织 Open Source Initiative 的负责人 Stefano Maffulli&#xff0c;他认为 Meta 正在混淆用户的理解&#xff0c;并对 “开源” 这一术语造成了污染。 Maffulli 指出&a…

ubuntu22.04 桌面系统怎么搭建一个esp-idf的项目,搭建开发环境

详细介绍如何在 Ubuntu 22.04 桌面系统上搭建 ESP-IDF 的开发环境&#xff0c;并创建一个 ESP-IDF 项目。以下内容将涵盖从环境准备到项目创建和编译的所有步骤。 目录 环境准备 1.1 更新系统1.2 安装必要的工具和依赖项 安装 ESP-IDF 2.1 克隆 ESP-IDF 仓库2.2 运行安装脚本 …

安全生产玩手机检测系统 玩手机识别系统 玩手机监测预警系统 使用 Python 和 OpenCV 库实现

在生产作业过程中&#xff0c;员工玩手机是一种极其危险的行为。它会分散员工的注意力&#xff0c;使其无法专注于工作任务。生产现场往往存在各种潜在的危险因素&#xff0c;如机械设备的运转、高空作业、化学品的使用等&#xff0c;一旦员工分心&#xff0c;就很容易忽视这些…

《深度学习》模型的部署、web框架 服务端及客户端案例

目录 一、模型的部署 1、模型部署的定义与目的 1&#xff09;定义 2&#xff09;目的 2、模型部署的步骤 1&#xff09;导出模型 2&#xff09; 部署模型 3&#xff09;测试模型 4&#xff09;监控模型 3、模型部署的方式 1&#xff09;云端部署 2&#xff09;嵌入…

【SpringCloud】03-Gateway网关

1. Gateway 网关&#xff1a;负责请求的路由、转发、身份校验。 2. Spring Cloud Gateway 依赖 <!--网关--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></de…

深入理解 Kafka

一、引言 在当今的大数据和分布式系统时代&#xff0c;高效的消息传递和处理是构建可靠、可扩展应用的关键。Apache Kafka 作为一种高吞吐量的分布式发布 - 订阅消息系统&#xff0c;在众多领域中发挥着重要作用。本文将深入探讨 Kafka 的核心概念、架构、工作原理、应用场景以…

python获取当前鼠标位置的RGB值

效果 依赖 pip install Pillow pyautoguisudo apt install gnome-screenshot代码 import pyautogui import timedef get_rgb_at_mouse():try:while True:# 获取当前鼠标的位置x, y pyautogui.position()# 截取当前屏幕图像screenshot pyautogui.screenshot()# 获取鼠标位置…

MySQL索引、事物与存储引擎

目录 一、MySQL索引 1.索引的概念 2.索引的作用 3.创建索引的原则依据 4.索引的分类和创建 4.1 普通索引 4.2 唯一索引 4.3 主键索引 4.4 组合索引&#xff08;单列索引与多列索引&#xff09; 4.5 全文索引&#xff08;FULLTEXT&#xff09; 5. 查看索引 6.删除索引…