Java识别文本中的敏感词汇

发布于:2024-10-15 ⋅ 阅读:(130) ⋅ 点赞:(0)

要想实现识别敏感词,那么我们就需要一个敏感词汇库,我们可以将敏感词放到一个.txt文件中,这里给大家上传一个我自己使用的词汇库

识别敏感词汇有一下几种方法

第一种方法:

敏感词库存储到了数据中,我们将文本内容与明杆词汇库中的敏感词进行匹配。在实际情况中我们不这样进行使用,这样使用对数据库的压力太大,影响我们的时间效率。

第二种方法:

用DFA帮助我们实现敏感词的识别,使用DFA之前,我在这里给大家简单的介绍一下什么是DFA。

DFA

DFA的核心算法就是建立以敏感词为基础的许多敏感词树(也就是字典树),它的基本思想是基于状态转移搜索敏感词。

字典树:字典树,是一种树形结构树形结构,主要用于统计,排序和保存大量的字符串。

主要思想:利用字符串的公共前缀来节约存储空间,很好地利用了串的公共前缀,节约了存储空间,字典树主要包含插入和查找两种操作

 

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;

public class SensitiveWordUtil {

    public static Map<String, Object> dictionaryMap = new HashMap<>();

    public static void main(String[] args) {

        // 定义要读取的文件路径和目标列表
        String filePath = "自己存放敏感词汇库的路径";
        List<String> dataList = new ArrayList<>();

        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
            String line;
            // 循环读取文件内容
            while ((line = br.readLine()) != null) {
                // 使用逗号作为分隔符,将字符串分割成列表元素
                String[] elements = line.split(",");
                for (String element : elements) {
                    dataList.add(element.trim()); // 确保移除每个元素两侧的空白字符
                }
            }


        } catch (IOException e) {
            e.printStackTrace();
        }
        //调用initMap函数,初始话词汇库
        initMap(dataList);
        String content="我是一个好人,并不会搞色情,也不用迷情药,更不会嫖娼,大肉棒";
        String content1="我是一个好人";
        //查看文章中是否包含敏感词
        Map<String, Integer> map = SensitiveWordUtil.matchWords(content);
        if(map.size() >0){

            System.out.println("敏感");
            System.out.println(map);

        }else {
            System.out.println("不敏感");
            System.out.println(map);
        }
    }
      


    /**
     * 生成关键词字典库
     * @param words
     * @return
     */
    public static void initMap(Collection<String> words) {
        if (words == null) {
            return ;
        }
        // map初始长度words.size(),整个字典库的入口字数(小于words.size(),因为不同的词可能会有相同的首字)
        Map<String, Object> map = new HashMap<>(words.size());
        // 遍历过程中当前层次的数据
        Map<String, Object> curMap = null;
        Iterator<String> iterator = words.iterator();
        while (iterator.hasNext()) {
            String word = iterator.next();
            curMap = map;
            int len = word.length();
            for (int i =0; i < len; i++) {
                // 遍历每个词的字
                String key = String.valueOf(word.charAt(i));
                // 当前字在当前层是否存在, 不存在则新建, 当前层数据指向下一个节点, 继续判断是否存在数据
                Map<String, Object> wordMap = (Map<String, Object>) curMap.get(key);
                if (wordMap == null) {
                    // 每个节点存在两个数据: 下一个节点和isEnd(是否结束标志)
                    wordMap = new HashMap<>(2);
                    wordMap.put("isEnd", "0");
                    curMap.put(key, wordMap);
                }
                curMap = wordMap; // 当前的wordMap层作为下次遍历的curMap层
                // 如果当前字是词的最后一个字,则将isEnd标志置1
                if (i == len -1) {
                    curMap.put("isEnd", "1");
                }
            }
        }
        dictionaryMap = map;
    }

    /**
     * 搜索文本中某个文字是否匹配关键词
     * @param text
     * @param beginIndex
     * @return
     */
    private static int checkWord(String text, int beginIndex) {
        if (dictionaryMap == null) {
            throw new RuntimeException("字典不能为空");
        }
        boolean isEnd = false;
        int wordLength = 0;
        Map<String, Object> curMap = dictionaryMap;
        int len = text.length();
        // 从文本的第beginIndex开始匹配
        for (int i = beginIndex; i < len; i++) {
            String key = String.valueOf(text.charAt(i));
            // 获取当前key的下一个节点
            curMap = (Map<String, Object>) curMap.get(key);
            if (curMap == null) {
                break;
            } else {
                wordLength ++;
                if ("1".equals(curMap.get("isEnd"))) {
                    isEnd = true;
                }
            }
        }
        if (!isEnd) {
            wordLength = 0;
        }
        return wordLength;
    }

    /**
     * 获取匹配的关键词和命中次数
     * @param text
     * @return
     */
    public static Map<String, Integer> matchWords(String text) {
        Map<String, Integer> wordMap = new HashMap<>();
        int len = text.length();
        for (int i = 0; i < len; i++) {
            int wordLength = checkWord(text, i);
            if (wordLength > 0) {
                String word = text.substring(i, i + wordLength);
                // 添加关键词匹配次数
                if (wordMap.containsKey(word)) {
                    wordMap.put(word, wordMap.get(word) + 1);
                } else {
                    wordMap.put(word, 1);
                }

                i += wordLength - 1;
            }
        }
        return wordMap;
    }
    /*public static boolean ScanSensitiveWord(String content) {
    }*/

}



网站公告

今日签到

点亮在社区的每一天
去签到