优秀的编程知识分享平台

网站首页 > 技术文章 正文

【开源项目】Java 推荐一款好用敏感词工具

nanyue 2025-02-27 16:05:13 技术文章 19 ℃

平时工作中,只要涉及到用户可以自由发言,比如博客,文档,论坛,就要考虑内容的敏感性处理,今天给大家分享一个敏感词汇处理工具:sensitive-word 基于 DFA 算法实现的高性能敏感词工具。

sensitive-word是一个基于 DFA 算法实现的高性能 java 敏感词过滤工具框架。

特性:

  • 6W+ 词库,且不断优化更新(源文件 18W+,经过一次删减)
  • 基于 fluent-api 实现,使用优雅简洁
  • 基于 DFA 算法,性能为 7W+ QPS,应用无感
  • 支持敏感词的判断、返回、脱敏等常见操作
  • 支持常见的格式转换

全角半角互换、英文大小写互换、数字常见形式的互换、中文繁简体互换、英文常见形式的互换、忽略重复词等

  • 支持敏感词检测、邮箱检测、数字检测、网址检测、IPV4等
  • 支持自定义替换策略
  • 支持用户自定义敏感词和白名单
  • 支持数据的数据动态更新(用户自定义),实时生效
  • 支持敏感词的标签接口
  • 支持跳过一些特殊字符,让匹配更灵活

使用教程:

Maven 引入


    com.github.houbb
    sensitive-word
    0.17.0

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

方法

参数

返回值

说明

contains(String)

待验证的字符串

布尔值

验证字符串是否包含敏感词

replace(String, ISensitiveWordReplace)

使用指定的替换策略替换敏感词

字符串

返回脱敏后的字符串

replace(String, char)

使用指定的 char 替换敏感词

字符串

返回脱敏后的字符串

replace(String)

使用 * 替换敏感词

字符串

返回脱敏后的字符串

findAll(String)

待验证的字符串

字符串列表

返回字符串中所有敏感词

findFirst(String)

待验证的字符串

字符串

返回字符串中第一个敏感词

findAll(String, IWordResultHandler)

IWordResultHandler 结果处理类

字符串列表

返回字符串中所有敏感词

findFirst(String, IWordResultHandler)

IWordResultHandler 结果处理类

字符串

返回字符串中第一个敏感词

tags(String)

获取敏感词的标签

敏感词字符串

返回敏感词的标签列表


判断是否包含敏感词


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

Assert.assertTrue(SensitiveWordHelper.contains(text));

返回第一个敏感词

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

String word = SensitiveWordHelper.findFirst(text);
Assert.assertEquals("五星红旗", word);


SensitiveWordHelper.findFirst(text) 等价于:

String word = SensitiveWordHelper.findFirst(text, WordResultHandlers.word());

返回所有敏感词:

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

List wordList = SensitiveWordHelper.findAll(text);
Assert.assertEquals("[五星红旗, 毛主席, 天安门]", wordList.toString());


返回所有敏感词用法上类似于
SensitiveWordHelper.findFirst(),同样也支持指定结果处理类。


SensitiveWordHelper.findAll(text) 等价于:

List wordList = SensitiveWordHelper.findAll(text, WordResultHandlers.word());

WordResultHandlers.raw() 可以保留对应的下标信息、类别信息:

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

// 默认敏感词标签为空
List wordList1 = SensitiveWordHelper.findAll(text, WordResultHandlers.wordTags());
Assert.assertEquals("[WordTagsDto{word='五星红旗', tags=[]}, WordTagsDto{word='毛主席', tags=[]}, WordTagsDto{word='天安门', tags=[]}]", wordList1.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);

自定义替换策略

V0.2.0 支持该特性。

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

诚然,提前使用字符串的正则替换也可以,不过性能一般。

使用例子:

/**
 * 自定替换策略
 * @since 0.2.0
 */
@Test
public void defineReplaceTest() {
    final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。";

    ISensitiveWordReplace replace = new MySensitiveWordReplace();
    String result = SensitiveWordHelper.replace(text, replace);

    Assert.assertEquals("国家旗帜迎风飘扬,教员的画像屹立在***前。", result);
}

其中 MySensitiveWordReplace 是我们自定义的替换策略,实现如下:

public class MyWordReplace implements IWordReplace {

    @Override
    public 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('*');
            }
        }
    }

}

我们针对其中的部分词做固定映射处理,其他的默认转换为 *。

还有更多特性功能,访问地址查看:
https://github.com/houbb/sensitive-word

Tags:

最近发表
标签列表