栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springboot 实现自动屏蔽敏感词过滤器

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springboot 实现自动屏蔽敏感词过滤器

1.编辑敏感词文本(.txt)

按行写入

2.编写过滤器 (1)创建前缀树保存敏感词
//前缀树
private class TireNode {
    //关键词结束标志
    private boolean isKeywordsEnd = false;
    //key是下级字符,value是下级节点(root为null)
    private Map sonNode = new HashMap<>();

    public boolean isKeywordsEnd() {
        return isKeywordsEnd;
    }

    public void setKeywordsEnd(boolean keywordsEnd) {
        isKeywordsEnd = keywordsEnd;
    }

    public void addSonNode(Character val, TireNode son) {
        sonNode.put(val, son);
    }

    public TireNode getSonNode(Character val) {
        return sonNode.get(val);
    }
}


标志代表是否是word结束,判断时若扫描结束节点非结束标志,则不视为敏感词。

(2)将文本导入
@PostConstruct
public void init() {
    try (   //将文件转化为字节流
            InputStream is = this.getClass().getClassLoader().getResourceAsStream("sensitive_words.txt");
            //将字节流转化为缓冲流
            BufferedReader reader = new BufferedReader(new InputStreamReader(is))
    ) {
        String keyword;
        while ((keyword = reader.readLine()) != null) {
            this.addKeywords(keyword);
        }
    } catch (Exception e) {
        logger.error("服务器加载敏感词失败" + e.getMessage());
    }
}
(3)将敏感词添加到前缀树
//将敏感词添加到前缀树
private void addKeywords(String keyword) {
    //指向root
    TireNode cur = tireNode;
    for (int i = 0; i < keyword.length(); i++) {
        //子节点中没有该字符
        if (cur.getSonNode(keyword.charAt(i)) == null) {
            //新建节点插入
            cur.addSonNode(keyword.charAt(i), new TireNode());
        }
        //指向下一个节点
        cur = cur.getSonNode(keyword.charAt(i));
        //设置标志位
        if (i == keyword.length() - 1) cur.setKeywordsEnd(true);
    }
}
(4)过滤敏感词
public String filter(String text) {
   if (text == null) return "";
   int main = 0, ass = 0;
   TireNode cur = tireNode;
   StringBuilder builder = new StringBuilder();
   while (ass < text.length()) {
       char c = text.charAt(ass);
       if (isSymbol(c)) {
           //如果主指针处于根节点,将此符号计入结果,让副指针继续走
           if (cur == tireNode) {
               builder.append(c);
               main++;
           }
           //副指针只要碰到符号就后移,主指针只有未开始匹配(树指针为根节点)时碰到符号才后移
           ass++;
           continue;
       }
       //寻找当前副指针指向的字符是否在树里
       cur = cur.getSonNode(c);
       //如果不在将主指针指向的字符压入builder,主指针向后移,树指针指向根节点
       if (cur == null) {
           builder.append(text.charAt(main));
           ass = ++main;
           cur = tireNode;
       } else if (cur.isKeywordsEnd()) {
           //如果副指针指向标志结束处,将代替符号压入builder,主副指针移至副指针后一个
           builder.append(REPLACEMENT);
           main = ++ass;
           cur = tireNode;
       } else {
           //否则副指针后移继续检查
           ass++;
       }
   }
   //将最后一批字符压入
   builder.append(text.substring(main));
   return builder.toString();
}

//判断是否为特殊符号
private boolean isSymbol(Character c) {
   //0x2E80~0x9FFF是东亚文字
   //CharUtils.isAsciiAlphanumeric判断是否为特殊符号
   return !CharUtils.isAsciiAlphanumeric(c) && (c < 0x2E80 || c > 0x9FFF);
}

当走到a时,树指针向下移动到a,副指针继续向后走
此时发现结束标记,将abc变为***,树指针指向root ps:要注意跳过特殊符号,防止敏感词中间加符号无法辨别,因此要检测是否为符号 3.测试


点击看gitee源码!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/781557.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号