敏感词过滤就是你在项目中输入某些字(比如输入xxoo相关的文字时)时要能检测出来,很多项目中都会有一个敏感词管理模块,在敏感词管理模块中你可以加入敏感词,然后根据加入的敏感词去过滤输入内容中的敏感词并进行相应的处理,要么提示,要么高亮显示,要么直接替换成其它的文字或者符号代替。
敏感词过滤的做法有很多,其中有比较常用的如下几种:
1.查询数据库当中的敏感词,循环每一个敏感词,然后去输入的文本中从头到尾搜索一遍,看是否存在此敏感词,有则做相应的处理,这种方式讲白了就是找到一个处理一个。
优点:so easy。用java代码实现基本没什么难度。
缺点:这效率是非常低的,如果是英文时你会发现一个很无语的事情,比如英文a是敏感词,那我如果是一篇英文文档,那程序它得处理多少次敏感词?谁能告诉我?
2.传说中的DFA算法(有限状态机),也正是我要给大家分享的,毕竟感觉比较通用,算法的原理希望大家能够自己去网上查查
资料,这里就不详细说明了。
优点:至少比上面那sb效率高点。
缺点:对于学过算法的应该不难,对于没学过算法的用起来也不难,就是理解起来有点gg疼,匹配效率也不高,比较耗费内存,
敏感词越多,内存占用的就越大。
在项目启动前读取数据,将敏感词加载到Map中,具体实现如下:
建表语句:
CREATE TABLE `sensitive_word` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',`content` varchar(50) NOT NULL COMMENT '关键词',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;INSERT INTO `fuying`.`sensitive_word` (`id`, `content`, `create_time`, `update_time`) VALUES (1, '吴名氏', '2023-03-02 14:21:36', '2023-03-02 14:21:36');
实体类SensitiveWord.java:
package com.wkf.workrecord.tools.dfa.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.io.Serializable;
import java.util.Date;/*** @author wuKeFan* @date 2023-03-02 13:48:58*/
@Data
@TableName("sensitive_word")
public class SensitiveWord implements Serializable {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.AUTO)private Integer id;private String content;private Date createTime;private Date updateTime;}
数据库持久类SensitiveWordMapper.java:
package com.wkf.workrecord.tools.dfa.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wkf.workrecord.tools.dfa.entity.SensitiveWord;/*** @author wuKeFan* @date 2023-03-02 13:50:16*/
public interface SensitiveWordMapper extends BaseMapper {
}
service类SensitiveWordService.java和SensitiveWordServiceImpl.java:
package com.wkf.workrecord.tools.dfa.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.wkf.workrecord.tools.dfa.entity.SensitiveWord;import java.util.Set;/*** 敏感词过滤服务类* @author wuKeFan* @date 2023-03-02 13:47:04*/
public interface SensitiveWordService extends IService {Set sensitiveWordFiltering(String text);}
package com.wkf.workrecord.tools.dfa.service;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wkf.workrecord.tools.dfa.mapper.SensitiveWordMapper;
import com.wkf.workrecord.tools.dfa.SensitiveWordUtils;
import com.wkf.workrecord.tools.dfa.entity.SensitiveWord;
import org.springframework.stereotype.Service;
import java.util.Set;/*** @author wuKeFan* @date 2023-03-02 13:48:04*/
@Service
public class SensitiveWordServiceImpl extends ServiceImpl implements SensitiveWordService{@Overridepublic Set sensitiveWordFiltering(String text) {// 得到敏感词有哪些,传入2表示获取所有敏感词return SensitiveWordUtils.getSensitiveWord(text, 2);}
}
敏感词过滤工具类SensitiveWordUtils:
package com.wkf.workrecord.tools.dfa;import com.wkf.workrecord.tools.dfa.entity.SensitiveWord;
import lombok.extern.slf4j.Slf4j;import java.util.*;/*** 敏感词过滤工具类* @author wuKeFan* @date 2023-03-02 13:45:19*/
@Slf4j
@SuppressWarnings("unused")
public class SensitiveWordUtils {/*** 敏感词库*/public static final Map
项目启动完成后执行初始化敏感关键字StartInit.java:
package com.wkf.workrecord.tools.dfa;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wkf.workrecord.tools.dfa.entity.SensitiveWord;
import com.wkf.workrecord.tools.dfa.mapper.SensitiveWordMapper;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;/*** 初始化敏感关键字* @author wuKeFan* @date 2023-03-02 13:57:45*/
@Component
public class StartInit {@Resourceprivate SensitiveWordMapper sensitiveWordMapper;@PostConstructpublic void init() {// 从数据库中获取敏感词对象集合(调用的方法来自Dao层,此方法是service层的实现类)List sensitiveWords = sensitiveWordMapper.selectList(new QueryWrapper<>());// 构建敏感词库SensitiveWordUtils.initKeyWord(sensitiveWords);}}
编写测试脚本测试效果.代码如下:
@Testpublic void sensitiveWordTest() {Set set = sensitiveWordService.sensitiveWordFiltering("吴名氏到此一游");for (String string : set) {System.out.println(string);}}
执行结果如下:
吴名氏为敏感词,匹配成功
上一篇:Python基础篇(十五)-- Pygame游戏编程
下一篇:224. 基本计算器