返回顶部
首页 > 资讯 > 后端开发 > Python >Java使用DFA算法实现敏感词过滤的示例代码
  • 496
分享到

Java使用DFA算法实现敏感词过滤的示例代码

JavaDFA敏感词过滤Java敏感词过滤 2023-03-24 11:03:11 496人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录1 前言2 代码实现2.1 敏感词库初始化2.2 编写测试类1 前言 敏感词过滤就是你在项目中输入某些字(比如输入xxoo相关的文字时)时要能检测出来,很多项目中都会有一个敏感词

1 前言

敏感词过滤就是你在项目中输入某些字(比如输入xxoo相关的文字时)时要能检测出来,很多项目中都会有一个敏感词管理模块,在敏感词管理模块中你可以加入敏感词,然后根据加入的敏感词去过滤输入内容中的敏感词并进行相应的处理,要么提示,要么高亮显示,要么直接替换成其它的文字或者符号代替。

敏感词过滤的做法有很多,其中有比较常用的如下几种:

1.查询数据库当中的敏感词,循环每一个敏感词,然后去输入的文本中从头到尾搜索一遍,看是否存在此敏感词,有则做相应的处理,这种方式讲白了就是找到一个处理一个。

优点:so easy。用java代码实现基本没什么难度。

缺点:这效率是非常低的,如果是英文时你会发现一个很无语的事情,比如英文a是敏感词,那我如果是一篇英文文档,那程序它得处理多少次敏感词?谁能告诉我?

2.传说中的DFA算法(有限状态机),也正是我要给大家分享的,毕竟感觉比较通用,算法的原理希望大家能够自己去网上查查

资料,这里就不详细说明了。

优点:至少比上面那sb效率高点。

缺点:对于学过算法的应该不难,对于没学过算法的用起来也不难,就是理解起来有点gg疼,匹配效率也不高,比较耗费内存,

敏感词越多,内存占用的就越大。

2 代码实现

2.1 敏感词库初始化

在项目启动前读取数据,将敏感词加载到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;
 

@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;
 

public interface SensitiveWordMapper extends BaseMapper<SensitiveWord> {
}

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;
 

public interface SensitiveWordService extends IService<SensitiveWord> {
 
    Set<String> 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;
 

@Service
public class SensitiveWordServiceImpl extends ServiceImpl<SensitiveWordMapper, SensitiveWord> implements SensitiveWordService{
 
    @Override
    public Set<String> 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.*;
 

@Slf4j
@SuppressWarnings("unused")
public class SensitiveWordUtils {
 
    
    public static final Map<Object, Object> sensitiveWordMap = new HashMap<>();
 
    
    public static int minMatchTYpe = 1;
 
    
    public static int maxMatchType = 2;
 
    
    public static void iniTKEyWord(List<SensitiveWord> sensitiveWords) {
        try {
            // 从敏感词集合对象中取出敏感词并封装到Set集合中
            Set<String> keyWordSet = new HashSet<>();
            for (SensitiveWord s : sensitiveWords) {
                keyWordSet.add(s.getContent().trim());
            }
            // 将敏感词库加入到HashMap中
            addSensitiveWordToHashMap(keyWordSet);
        }
        catch (Exception e) {
            log.error("初始化敏感词出错,", e);
        }
    }
 
    
    private static void addSensitiveWordToHashMap(Set<String> keyWordSet) {
        // 敏感词
        String key;
        // 用来按照相应的格式保存敏感词库数据
        Map<Object, Object> nowMap;
        // 用来辅助构建敏感词库
        Map<Object, Object> newWORMap;
        // 使用一个迭代器来循环敏感词集合
        for (String s : keyWordSet) {
            key = s;
            // 等于敏感词库,HashMap对象在内存中占用的是同一个地址,所以此nowMap对象的变化,sensitiveWordMap对象也会跟着改变
            nowMap = sensitiveWordMap;
            for (int i = 0; i < key.length(); i++) {
                // 截取敏感词当中的字,在敏感词库中字为HashMap对象的Key键值
                char keyChar = key.charAt(i);
 
                // 判断这个字是否存在于敏感词库中
                Object wordMap = nowMap.get(keyChar);
                if (wordMap != null) {
                    nowMap = (Map<Object, Object>) wordMap;
                } else {
                    newWorMap = new HashMap<>();
                    newWorMap.put("isEnd", "0");
                    nowMap.put(keyChar, newWorMap);
                    nowMap = newWorMap;
                }
 
                // 如果该字是当前敏感词的最后一个字,则标识为结尾字
                if (i == key.length() - 1) {
                    nowMap.put("isEnd", "1");
                }
                log.info("封装敏感词库过程:" + sensitiveWordMap);
            }
            log.info("查看敏感词库数据:" + sensitiveWordMap);
        }
    }
 
    
    public static int getWordSize() {
        return SensitiveWordUtils.sensitiveWordMap.size();
    }
 
    
    public static boolean isContainSensitiveWord(String txt, int matchType) {
        boolean flag = false;
        for (int i = 0; i < txt.length(); i++) {
            int matchFlag = checkSensitiveWord(txt, i, matchType);
            if (matchFlag > 0) {
                flag = true;
            }
        }
        return flag;
    }
 
    
    public static Set<String> getSensitiveWord(String txt, int matchType) {
        Set<String> sensitiveWordList = new HashSet<>();
 
        for (int i = 0; i < txt.length(); i++) {
            int length = checkSensitiveWord(txt, i, matchType);
            if (length > 0) {
                // 将检测出的敏感词保存到集合中
                sensitiveWordList.add(txt.substring(i, i + length));
                i = i + length - 1;
            }
        }
        return sensitiveWordList;
    }
 
    
    public static String replaceSensitiveWord(String txt, int matchType, String replaceChar) {
        String resultTxt = txt;
        Set<String> set = getSensitiveWord(txt, matchType);
        Iterator<String> iterator = set.iterator();
        String word;
        String replaceString;
        while (iterator.hasNext()) {
            word = iterator.next();
            replaceString = getReplaceChars(replaceChar, word.length());
            resultTxt = resultTxt.replaceAll(word, replaceString);
        }
 
        return resultTxt;
    }
 
    
    private static String getReplaceChars(String replaceChar, int length) {
        StringBuilder resultReplace = new StringBuilder(replaceChar);
        for (int i = 1; i < length; i++) {
            resultReplace.append(replaceChar);
        }
        return resultReplace.toString();
    }
 
    
    public static int checkSensitiveWord(String txt, int beginIndex, int matchType) {
        boolean flag = false;
        // 记录敏感词数量
        int matchFlag = 0;
        char word;
        Map<Object, Object> nowMap = SensitiveWordUtils.sensitiveWordMap;
        for (int i = beginIndex; i < txt.length(); i++) {
            word = txt.charAt(i);
            // 判断该字是否存在于敏感词库中
            nowMap = (Map<Object, Object>) nowMap.get(word);
            if (nowMap != null) {
                matchFlag++;
                // 判断是否是敏感词的结尾字,如果是结尾字则判断是否继续检测
                if ("1".equals(nowMap.get("isEnd"))) {
                    flag = true;
                    // 判断过滤类型,如果是小过滤则跳出循环,否则继续循环
                    if (SensitiveWordUtils.minMatchTYpe == matchType) {
                        break;
                    }
                }
            }
            else {
                break;
            }
        }
        if (!flag) {
            matchFlag = 0;
        }
        return matchFlag;
    }
 
}

项目启动完成后执行初始化敏感关键字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;
 

@Component
public class StartInit {
 
    @Resource
    private SensitiveWordMapper sensitiveWordMapper;
 
    @PostConstruct
    public void init() {
        // 从数据库中获取敏感词对象集合(调用的方法来自Dao层,此方法是service层的实现类)
        List<SensitiveWord> sensitiveWords = sensitiveWordMapper.selectList(new QueryWrapper<>());
        // 构建敏感词库
        SensitiveWordUtils.initKeyWord(sensitiveWords);
    }
 
}

2.2 编写测试类

编写测试脚本测试效果.代码如下:

    @Test
    public void sensitiveWordTest() {
        Set<String> set = sensitiveWordService.sensitiveWordFiltering("吴名氏到此一游");
        for (String string : set) {
            System.out.println(string);
        }
    }

执行结果如下:

到此这篇关于Java使用DFA算法实现敏感词过滤的示例代码的文章就介绍到这了,更多相关Java DFA敏感词过滤内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java使用DFA算法实现敏感词过滤的示例代码

本文链接: https://lsjlt.com/news/201162.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java使用DFA算法实现敏感词过滤的示例代码
    目录1 前言2 代码实现2.1 敏感词库初始化2.2 编写测试类1 前言 敏感词过滤就是你在项目中输入某些字(比如输入xxoo相关的文字时)时要能检测出来,很多项目中都会有一个敏感词...
    99+
    2023-03-24
    Java DFA敏感词过滤 Java 敏感词过滤
  • Java怎么使用DFA算法实现敏感词过滤
    本篇内容主要讲解“Java怎么使用DFA算法实现敏感词过滤”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java怎么使用DFA算法实现敏感词过滤”吧!1 前言敏感词过滤就是你在项目中输入某些字(...
    99+
    2023-07-05
  • 怎么在Java中使用DFA算法过滤敏感词
    怎么在Java中使用DFA算法过滤敏感词?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。具体实现: 1、匹配大小写过滤 2、匹配全角半角过滤 3...
    99+
    2023-05-30
    java dfa
  • 如何在java中使用DFA算法过滤敏感词
    如何在java中使用DFA算法过滤敏感词?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。敏感词过滤的做法有很多,我简单描述我现在理解的几种:①查询数据库当中的敏感词,循环每一...
    99+
    2023-05-31
    java ava dfa算法
  • SpringBoot实现过滤敏感词的示例代码
    过滤敏感词 1. 创建一个储存要过滤的敏感词的文本文件 首先创建一个文本文件储存要过滤的敏感词 在下面的工具类中我们会读取这个文本文件,这里提前给出 @PostConstruct...
    99+
    2022-11-13
    SpringBoot过滤敏感词 SpringBoot 敏感词
  • Python基于DFA算法实现内容敏感词过滤
    DFA 算法是通过提前构造出一个 树状查找结构,之后根据输入在该树状结构中就可以进行非常高效的查找。 设我们有一个敏感词库,词酷中的词汇为: 我爱你我爱他我爱她我爱你呀我爱他呀我爱她...
    99+
    2024-04-02
  • Python基于DFA算法怎么实现内容敏感词过滤
    这篇文章主要讲解了“Python基于DFA算法怎么实现内容敏感词过滤”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python基于DFA算法怎么实现内容敏感词过滤”吧!DFA 算法是通过提前...
    99+
    2023-06-30
  • Python 敏感词过滤的实现示例
    目录 一个简单的实现使用BSF(宽度优先搜索)进行实现 使用DFA(Deterministic Finite Automaton)进行实现  一个简单的实现 主要...
    99+
    2024-04-02
  • SpringBoot使用SensitiveWord实现敏感词过滤
    目录导入依赖方法默认示例自定义替换策略示例自定义自定义SensitiveWordBs自定义敏感词白名单自定义敏感词黑名单示例重置词库总结包含默认敏感词过滤和自定义敏感词过滤。 导入依...
    99+
    2023-01-14
    SpringBoot SensitiveWord敏感词过滤 SpringBoot 敏感词过滤 SpringBoot SensitiveWord
  • SpringBoot使用前缀树过滤敏感词的方法实例
    目录一、前缀树二、敏感词过滤器总结一、前缀树 一般设计网站的时候,会有问题发布或者是内容发布的功能,这些功能的有一个很重要的点在于如何实现敏感词过滤,要不然可能会有不良信息的发布,或...
    99+
    2024-04-02
  • 如何在Java项目中利用DFA算法实现一个过滤敏感字功能
    这期内容当中小编将会给大家带来有关如何在Java项目中利用DFA算法实现一个过滤敏感字功能,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。模式图直接上代码public class KeywordFilter...
    99+
    2023-05-31
    java dfa算法 ava
  • JAVA使用前缀树(Tire树)实现敏感词过滤、词典搜索
    目录简介Trie树code结论简介 有时候需要对用户输入的内容进行敏感词过滤,或者实现查找文本中出现的词典中的词,用遍历的方式进行替换或者查找效率非常低,这里提供一个基于Trie树的...
    99+
    2023-01-03
    JAVA前缀树敏感词过滤 JAVA前缀树
  • SpringBoot使用前缀树过滤敏感词的方法是什么
    这篇文章跟大家分析一下“SpringBoot使用前缀树过滤敏感词的方法是什么”。内容详细易懂,对“SpringBoot使用前缀树过滤敏感词的方法是什么”感兴趣的朋友可以跟着小编的思路慢慢深入来阅读一下,希望阅读后能够对大家有所帮助。下面跟着...
    99+
    2023-06-26
  • Java实现Floyd算法的示例代码
    目录一 问题描述二 代码三 实现一 问题描述 求节点0到节点2的最短路径。 二 代码 package graph.floyd; ...
    99+
    2024-04-02
  • Java实现Kruskal算法的示例代码
    目录介绍一、构建后的图二、代码三、测试介绍 构造最小生成树还有一种算法,即 Kruskal 算法:设图 G=(V,E)是无向连通带权图,V={1,2,...n};设最小生成树 T=(...
    99+
    2024-04-02
  • Java实现Dijkstra算法的示例代码
    目录一 问题描述二 实现三 测试一 问题描述 小明为位置1,求他到其他各顶点的距离。 二 实现 package graph.dij...
    99+
    2024-04-02
  • django filters实现数据过滤的示例代码
    常用 当前循环. 作用 ...
    99+
    2024-04-02
  • Java实现雪花算法的示例代码
    一、介绍 SnowFlow算法是Twitter推出的分布式id生成算法,主要核心思想就是利用64bit的long类型的数字作为全局的id。在分布式系统中经常应用到,并且,在id中加入...
    99+
    2024-04-02
  • Java实现抽奖算法的示例代码
    目录一、题目描述二、解题思路三、代码详解四、优化抽奖算法解题思路代码详解一、题目描述 题目: 小虚竹为了给粉丝送福利,决定在参与学习打卡活动的粉丝中抽一位幸运粉丝,送份小礼物。为了公...
    99+
    2024-04-02
  • SpringBoot+Redis实现布隆过滤器的示例代码
    目录简述Redis 安装 Bloom Filter基本指令结合 SpingBoot方式一方式二简述 关于布隆过滤器的详细介绍,我在这里就不再赘述一遍了 我们首先知道:BloomFil...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作