最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java使用DFA算法實現(xiàn)敏感詞過濾的示例代碼

 更新時間:2023年03月24日 10:56:57   作者:吳名氏  
很多項目中都會有一個敏感詞管理模塊,本文主要介紹了Java使用DFA算法實現(xiàn)敏感詞過濾的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

1 前言

敏感詞過濾就是你在項目中輸入某些字(比如輸入xxoo相關的文字時)時要能檢測出來,很多項目中都會有一個敏感詞管理模塊,在敏感詞管理模塊中你可以加入敏感詞,然后根據(jù)加入的敏感詞去過濾輸入內(nèi)容中的敏感詞并進行相應的處理,要么提示,要么高亮顯示,要么直接替換成其它的文字或者符號代替。

敏感詞過濾的做法有很多,其中有比較常用的如下幾種:

1.查詢數(shù)據(jù)庫當中的敏感詞,循環(huán)每一個敏感詞,然后去輸入的文本中從頭到尾搜索一遍,看是否存在此敏感詞,有則做相應的處理,這種方式講白了就是找到一個處理一個。

優(yōu)點:so easy。用java代碼實現(xiàn)基本沒什么難度。

缺點:這效率是非常低的,如果是英文時你會發(fā)現(xiàn)一個很無語的事情,比如英文a是敏感詞,那我如果是一篇英文文檔,那程序它得處理多少次敏感詞?誰能告訴我?

2.傳說中的DFA算法(有限狀態(tài)機),也正是我要給大家分享的,畢竟感覺比較通用,算法的原理希望大家能夠自己去網(wǎng)上查查

資料,這里就不詳細說明了。

優(yōu)點:至少比上面那sb效率高點。

缺點:對于學過算法的應該不難,對于沒學過算法的用起來也不難,就是理解起來有點gg疼,匹配效率也不高,比較耗費內(nèi)存,

敏感詞越多,內(nèi)存占用的就越大。

2 代碼實現(xiàn)

2.1 敏感詞庫初始化

在項目啟動前讀取數(shù)據(jù),將敏感詞加載到Map中,具體實現(xiàn)如下:

建表語句:

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 '創(chuàng)建時間',
  `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;
 
}

數(shù)據(jù)庫持久類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<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;
 
/**
 * 敏感詞過濾服務類
 * @author wuKeFan
 * @date 2023-03-02 13:47:04
 */
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;
 
/**
 * @author wuKeFan
 * @date 2023-03-02 13:48:04
 */
@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.*;
 
/**
 * 敏感詞過濾工具類
 * @author wuKeFan
 * @date 2023-03-02 13:45:19
 */
@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);
        }
    }
 
    /**
     * 封裝敏感詞庫
     *
     * @param keyWordSet 敏感詞庫列表
     */
    private static void addSensitiveWordToHashMap(Set<String> keyWordSet) {
        // 敏感詞
        String key;
        // 用來按照相應的格式保存敏感詞庫數(shù)據(jù)
        Map<Object, Object> nowMap;
        // 用來輔助構建敏感詞庫
        Map<Object, Object> newWorMap;
        // 使用一個迭代器來循環(huán)敏感詞集合
        for (String s : keyWordSet) {
            key = s;
            // 等于敏感詞庫,HashMap對象在內(nèi)存中占用的是同一個地址,所以此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("查看敏感詞庫數(shù)據(jù):" + sensitiveWordMap);
        }
    }
 
    /**
     * 敏感詞庫敏感詞數(shù)量
     *
     * @return 返回數(shù)量
     */
    public static int getWordSize() {
        return SensitiveWordUtils.sensitiveWordMap.size();
    }
 
    /**
     * 是否包含敏感詞
     *
     * @param txt 敏感詞
     * @param matchType 匹配類型
     * @return 返回結果
     */
    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;
    }
 
    /**
     * 獲取敏感詞內(nèi)容
     *
     * @param txt 敏感詞
     * @param matchType 匹配類型
     * @return 敏感詞內(nèi)容
     */
    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;
    }
 
    /**
     * 替換敏感詞
     *
     * @param txt 敏感詞
     * @param matchType 匹配類型
     * @param replaceChar 代替詞
     * @return 返回敏感詞
     */
    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;
    }
 
    /**
     * 替換敏感詞內(nèi)容
     *
     * @param replaceChar 需要替換的敏感詞
     * @param length 替換長度
     * @return 返回結果
     */
    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();
    }
 
    /**
     * 檢查敏感詞數(shù)量
     *
     * @param txt 敏感詞
     * @param beginIndex 開始下標
     * @param matchType 匹配類型
     * @return 返回數(shù)量
     */
    public static int checkSensitiveWord(String txt, int beginIndex, int matchType) {
        boolean flag = false;
        // 記錄敏感詞數(shù)量
        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++;
                // 判斷是否是敏感詞的結尾字,如果是結尾字則判斷是否繼續(xù)檢測
                if ("1".equals(nowMap.get("isEnd"))) {
                    flag = true;
                    // 判斷過濾類型,如果是小過濾則跳出循環(huán),否則繼續(xù)循環(huán)
                    if (SensitiveWordUtils.minMatchTYpe == matchType) {
                        break;
                    }
                }
            }
            else {
                break;
            }
        }
        if (!flag) {
            matchFlag = 0;
        }
        return matchFlag;
    }
 
}

項目啟動完成后執(zhí)行初始化敏感關鍵字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 {
 
    @Resource
    private SensitiveWordMapper sensitiveWordMapper;
 
    @PostConstruct
    public void init() {
        // 從數(shù)據(jù)庫中獲取敏感詞對象集合(調(diào)用的方法來自Dao層,此方法是service層的實現(xiàn)類)
        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);
        }
    }

執(zhí)行結果如下:

到此這篇關于Java使用DFA算法實現(xiàn)敏感詞過濾的示例代碼的文章就介紹到這了,更多相關Java DFA敏感詞過濾內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • SpringBoot使用@Async注解實現(xiàn)異步調(diào)用

    SpringBoot使用@Async注解實現(xiàn)異步調(diào)用

    這篇文章主要介紹了SpringBoot使用@Async注解實現(xiàn)異步調(diào)用,異步調(diào)用是相對于同步調(diào)用而言的,同步調(diào)用是指程序按預定順序一步步執(zhí)行,每一步必須等到上一步執(zhí)行完后才能執(zhí)行,異步調(diào)用則無需等待,程序執(zhí)行完即可執(zhí)行,可以減少程序執(zhí)行時間,需要的朋友可以參考下
    2023-10-10
  • java中Struts2 的文件上傳和下載示例

    java中Struts2 的文件上傳和下載示例

    這篇文章主要介紹了java中Struts2 的文件上傳和下載示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。
    2016-12-12
  • java  自定義注解的實例詳解

    java 自定義注解的實例詳解

    這篇文章主要介紹了java 自定義注解的實例詳解的相關資料,需要的朋友可以參考下
    2017-09-09
  • spring data jpa開啟批量插入、批量更新的問題解析

    spring data jpa開啟批量插入、批量更新的問題解析

    這篇文章主要介紹了spring data jpa開啟批量插入、批量更新問題,本文通過圖文實例相結合給大家介紹的非常詳細,需要的朋友可以參考下
    2021-07-07
  • Java初學之繼承與多態(tài)

    Java初學之繼承與多態(tài)

    這篇文章主要介紹了Java 繼承與多態(tài)的深入理解的相關資料,子類繼承父類的特征和行為,使得子類具有父類的各種屬性和方法?;蜃宇悘母割惱^承方法,使得子類具有父類相同的行為,需要的朋友可以參考下
    2021-07-07
  • idea項目結構中不顯示out文件夾的解決

    idea項目結構中不顯示out文件夾的解決

    本文通過圖片的方式詳細解釋操作步驟,使讀者能夠更直觀更方便地理解和執(zhí)行操作,同時,文章末尾祝福讀者步步高升,一帆風順,展現(xiàn)了作者的人情味和親和力,整體來說,這是一篇簡單易懂、實用性強的操作指南
    2024-10-10
  • java使用poi讀取doc和docx文件的實現(xiàn)示例

    java使用poi讀取doc和docx文件的實現(xiàn)示例

    這篇文章主要介紹了java使用poi讀取doc和docx文件的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03
  • maven如何使用slf4j輸出日志到文件

    maven如何使用slf4j輸出日志到文件

    這篇文章主要介紹了maven如何使用slf4j輸出日志到文件,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • NoHttpResponseException問題排查解決記錄分析

    NoHttpResponseException問題排查解決記錄分析

    這篇文章主要為大家介紹了NoHttpResponseException問題排查解決記錄分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • Java單例模式的深入了解

    Java單例模式的深入了解

    這篇文章主要為大家介紹了Java單例模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01

最新評論

绍兴市| 施甸县| 新晃| 兰西县| 桐梓县| 高雄市| 潞西市| 页游| 和平区| 龙州县| 张掖市| 响水县| 大渡口区| 黑山县| 德格县| 阿瓦提县| 乌拉特前旗| 西城区| 通州区| 仪陇县| 克山县| 拜城县| 义乌市| 龙门县| 睢宁县| 开江县| 榆林市| 怀远县| 铜山县| 揭阳市| 蓝山县| 溧水县| 甘南县| 无为县| 清水河县| 新民市| 锡林浩特市| 夏津县| 雅江县| 安溪县| 平乐县|