简单的敏感词提示功能

简单的敏感词提示功能

1. 需求

公司现在接到通知,部分接口的部分手动输入字段,需要新增敏感词报红提示,敏感词汇现在应该是7000多个左右,需要我们提供一个敏感词校验接口,如果前端输入敏感词,则前端提示出输入的非法敏感词信息,并且分词需要支持自定义字典信息。

2.具体实现

此接口的实现过程也是相对简单,主要是使用java的分词器进行前端输入字符串代码分词,然后使用分词后的结果集与数据库中的数据进行比对,如果比对成功,则证明前端页面字符输入有非法的敏感词汇,返回给前端提示即可,数据库中数据则是在服务启动的时候加载到服务内存中,以hashSet形式进行存储(因为hashSet.contains方法效率比较高)

具体的简单实现步骤如下:

  • 引入分词器pom坐标
  • 添加自定义分词字典文件
  • 初始化加载数据库数据,加载自定义分词字典
  • 编写判定接口,进行敏感字判定

自定义词典格式要求,词典格式和dict.txt 一样,一个词占一行;每一行分三部分:词语、词频(可省略)、词性(可省略),用空格隔开,顺序不可颠倒。具体词性列表如下所示:

参数 类型 含义解释
Ag 形语素 形容词性语素。形容词代码为 a,语素代码g前面置以A。
a 形容词 取英语形容词 adjective 的第1个字母。
ad 副形词 直接作状语的形容词。形容词代码 a和副词代码d并在一起。
an 名形词 具有名词功能的形容词。形容词代码 a和名词代码n并在一起。
b 区别词 取汉字"别"的声母。
c 连词 取英语连词 conjunction的第1个字母。
dg 副语素 副词性语素。副词代码为 d,语素代码g前面置以D。
d 副词 adverb的第2个字母,因其第1个字母已用于形容词。
e 叹词 取英语叹词 exclamation的第1个字母。
f 方位词 取汉字"方"
g 语素 绝大多数语素都能作为合成词的"词根",取汉字"根"的声母。
h 前接成分 取英语 head的第1个字母。
i 成语 取英语成语 idiom的第1个字母。
j 简称略语 取汉字"简"的声母。
k 后接成分
l 习用语 习用语尚未成为成语,有点"临时性",取"临"的声母。
m 数词 取英语 numeral的第3个字母,n,u已有他用。
Ng 名语素 名词性语素。名词代码为 n,语素代码g前面置以N。
n 名词 取英语名词 noun的第1个字母。
nr 人名 名词代码 n和"人(ren)"的声母并在一起。
ns 地名 名词代码 n和处所词代码s并在一起。
nt 机构团体 "团"的声母为 t,名词代码n和t并在一起。
nz 其他专名 "专"的声母的第 1个字母为z,名词代码n和z并在一起。
o 拟声词 取英语拟声词 onomatopoeia的第1个字母。
p 介词 取英语介词 prepositional的第1个字母。
q 量词 取英语 quantity的第1个字母。
r 代词 取英语代词 pronoun 的第2个字母,因p已用于介词。
s 处所词 取英语 space 的第1个字母。
tg 时语素 时间词性语素。时间词代码为 t,在语素的代码g前面置以T。
t 时间词 取英语 time的第1个字母。
u 助词 取英语助词 auxiliary
vg 动语素 动词性语素。动词代码为 v。在语素的代码g前面置以V。
v 动词 取英语动词 verb的第一个字母。
vd 副动词 直接作状语的动词。动词和副词的代码并在一起。
vn 名动词 指具有名词功能的动词。动词和名词的代码并在一起。
w 标点符号
x 非语素字 非语素字只是一个符号,字母 x通常用于代表未知数、符号。
y 语气词 取汉字"语"的声母。
z 状态词 取汉字"状"的声母的前一个字母。
un 未知词 不可识别词及用户自定义词组。取英文 Unkonwn首两个字母。(非北大标准,CSW分词中定义)

3. 代码部分

  • 引入pom信息

    xml 复制代码
    <!-- 结巴分词 -->
    <dependency>
        <groupId>com.huaban</groupId>
        <artifactId>jieba-analysis</artifactId>
        <version>1.0.2</version>
    </dependency>
  • 添加自定义分词字典文件

    在resources目录下添加新的分词文件

  • 初始化加载数据库数据,加载自定义分词字典

    java 复制代码
    package cn.git.init;
    
    import com.huaban.analysis.jieba.WordDictionary;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.PostConstruct;
    import java.io.File;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.util.HashSet;
    import java.util.Objects;
    import java.util.Set;
    
    /**
     * @description: 自定义分词词典加载初始化
     * @program: bank-credit-sy
     * @author: lixuchun
     * @create: 2024-08-13
     */
    @Slf4j
    @Component
    public class AnalyzerInit {
    
        /**
         * 敏感词集合
         */
        public static Set<String> sensitiveWordsSet = new HashSet<>();
    
        /**
         * 自定义词典路径
         */
        private static final String DICT_PATH = "dict/custom.dict";
    
        /**
         * 初始化加载自定义分词词典
         */
        @PostConstruct
        public void analyzerInit() {
            // 获取自定义词典信息
            String dictFilePath = Objects.requireNonNull(getClass().getClassLoader().getResource(DICT_PATH)).getPath();
            Path path = Paths.get(new File(dictFilePath).getAbsolutePath());
    
            log.info("开始加载分词词典信息,获取自定义词典路径[{}]", dictFilePath);
    
            //加载自定义的词典进词库
            WordDictionary.getInstance().loadUserDict(path);
            log.info("加载自定义词典信息完毕");
    
            // 开始加载数据库中敏感词信息,大写字母修改为小写字母,此过程正常应该是在数据库中获取
            for (int i = 0; i < 1000000; i++) {
                if (i == 0) {
                    sensitiveWordsSet.add("傻x");
                    sensitiveWordsSet.add("牛p");
                    sensitiveWordsSet.add("先烈的电话");
                } else {
                    sensitiveWordsSet.add("傻x" + i);
                    sensitiveWordsSet.add("牛p" + i);
                }
            }
            log.info("数据库中敏感分词加载完毕!");
        }
    }
  • 编写判定接口,进行敏感字判定

    java 复制代码
    package cn.git.analysis;
    
    import cn.git.init.AnalyzerInit;
    import com.alibaba.fastjson.JSONObject;
    import com.huaban.analysis.jieba.JiebaSegmenter;
    import com.huaban.analysis.jieba.SegToken;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @description: 分词测试controller
     * @program: bank-credit-sy
     * @author: lixuchun
     * @create: 2024-08-13
     */
    @RestController
    @RequestMapping("/analyzer")
    public class AnalyzerController {
    
        /**
         * 分词测试方法
         */
        @GetMapping("/test")
        public String test() {
            // 创建分词对象
            JiebaSegmenter jiebaSegmenter = new JiebaSegmenter();
    
            // 其中傻X是自定义分词,正常接收到字符串首先去除空格,然后调用分词方法
            String[] sentences = new String[] {
                    "傻X上海这是一个伸手不见五指的黑夜。我叫孙悟空咸阳6合彩,我爱北京,我爱Python和C++。h动画", "我不喜欢日本和服。", "雷猴回归人间。",
                    "工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作先烈的电话,牛p啊", "结果婚的和尚未结过婚的666"
            };
    
            // 进行分词展示
            List<String> sentenceWordList = new ArrayList<>();
            for (String sentence : sentences) {
                List<SegToken> process = jiebaSegmenter.process(sentence, JiebaSegmenter.SegMode.INDEX);
                process.forEach(segToken -> {
                    if (AnalyzerInit.sensitiveWordsSet.contains(segToken.word)) {
                        sentenceWordList.add(segToken.word);
                    }
                });
            }
    
            // 输出敏感词汇
            return JSONObject.toJSONString(sentenceWordList);
        }
    }

4.测试部分

使用请求简单测试 http://localhost:8089/analyzer/test,返回敏感词信息结果如下

相关推荐
m0_571957581 小时前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
魔道不误砍柴功3 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2343 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨3 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
测开小菜鸟4 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity5 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天5 小时前
java的threadlocal为何内存泄漏
java
caridle6 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^6 小时前
数据库连接池的创建
java·开发语言·数据库
苹果醋36 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx