java敏感词校验

背景

在做一些跟内容相关的项目的时候,经常需要对内容文本中的内容进行检测,检测文本中是否包含某个敏感、违法等词汇,例如“贷款”、“发票”之类的。有些狡猾的用户可能知道“贷款”在你的系统中是敏感词,不能审核通过,便使用“贷 款”、“贷$款”、"贷;款"等这种方式故意欺骗你的系统,从而系统无法简单找出这些敏感词。敏感词一般都是中文分词后的单个词,不排除想要不分词处理的敏感词,这种情况可能影响到最终校验结果。

解决方案

方案一:使用List的contains方法检测文本中是否有敏感词,简单粗暴

最容易想到的,将所有敏感词存放在List中,每次需要检测文本中是否有敏感词的时候,for循环list列表,使用contains方法判断文本中是否包含关键词,如果有则返回true,如果循环结束还没有找到的话则不包含敏感词。代码大概如下:

String text="贷款测试";
for(String str: blackList){if(text.contains(str)){return true;}
}
return false;

使用这种方式的优点就是简单,但是每次检测的时候,如果文本中没有敏感词,都需要把每个敏感词循环一遍,如果系统对性能要求比较高,可能速度满足不了性能需求。

方案二:使用开源项目https://github.com/toolgood/ToolGood.Words,目前版本有升级,一些方法可能过时,使用最新得实现方法就可以了。

1、将所有敏感词加载到List

public static List<String> loadKeywords(File file){List<String> keyArray=new ArrayList<String>();try{BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件String s = null;while((s = br.readLine())!=null){//使用readLine方法,一次读一行keyArray.add(s);}br.close();}catch(Exception e){e.printStackTrace();}return keyArray;}

示例代码是从txt文本文件中加载黑词,在我们实际项目中可以改为从数据库中读取

2、定义IllegalWordsSearch对象

IllegalWordsSearch iwords = new IllegalWordsSearch();
iwords.SetKeywords(list);

3、使用IllegalWordsSearch敏感词过滤方法,常用的有如下:

(1)ContainsAny 判断文本是否包含关键字

(2)FindFirst 找出文本中第一个关键字

(3)FindAll 在文本中查找所有的关键字

eg:

maven依赖:

<dependency>
    <groupId>io.github.toolgood</groupId>
    <artifactId>toolgood-words</artifactId>
    <version>3.0.3.1</version>
</dependency>

<dependency><groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.15</version>
</dependency>
        String test = "我有一颗大土豆,刚出锅的夜场.票d女模特";
        // 可以对test先格式化,去除标点符号、空格等
        List<String> list=new ArrayList<String>();
        list.add("夜场女模特");
        list.add("发票");
//        list.add("模特");
        StringSearch iwords = new StringSearch();
        iwords.SetKeywords(list);
        boolean b = iwords.ContainsAny(test);
        System.out.println("b="+b);

值得一提的是它支持过滤跳词,即如果你的关键词为“贷款”,如果文本是“贷 款”、“贷;款”之类的也是可以识别的。

作者在项目中也给出了速度测试结果,速度也很不错。

另外项目中也包含一些繁体简体互转,汉字转拼音,中文数字互转的功能,值得推荐!!!

解决方案三:使用hutool中的dfa

<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.4.1</version>
</dependency>
public static void main(String[] args) {WordTree tree = new WordTree();tree.addWord("彩票");tree.addWord("发票");Filter<Character> charFilter = StopChar::isNotStopChar;tree.setCharFilter(charFilter);//正文String text = "我有一颗大土豆,刚出锅的彩.票发票";System.out.println(tree.isMatch(text));List<String> matchAll = tree.matchAll(text, -1, false, false);System.out.println(matchAll);
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Java代码示例,用于实现敏感字体检测: ```java import java.util.*; public class SensitiveWordFilter { private TrieNode rootNode; public SensitiveWordFilter(Set<String> sensitiveWords) { rootNode = new TrieNode(); for (String word : sensitiveWords) { addWordToTrie(word); } } private void addWordToTrie(String word) { TrieNode node = rootNode; for (char c : word.toCharArray()) { node = node.addChild(c); } node.setEndOfWord(true); } public String filter(String text) { StringBuilder result = new StringBuilder(); TrieNode node = rootNode; int start = 0; for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); if (node.hasChild(c)) { node = node.getChild(c); if (node.isEndOfWord()) { result.append("*".repeat(i - start + 1)); start = i + 1; node = rootNode; } } else { result.append(text.charAt(start)); start++; i = start - 1; node = rootNode; } } result.append(text.substring(start)); return result.toString(); } private static class TrieNode { private Map<Character, TrieNode> children; private boolean endOfWord; public TrieNode() { children = new HashMap<>(); } public TrieNode addChild(char c) { return children.computeIfAbsent(c, key -> new TrieNode()); } public TrieNode getChild(char c) { return children.get(c); } public boolean hasChild(char c) { return children.containsKey(c); } public boolean isEndOfWord() { return endOfWord; } public void setEndOfWord(boolean endOfWord) { this.endOfWord = endOfWord; } } } ``` 使用示例: ```java Set<String> sensitiveWords = new HashSet<>(Arrays.asList("敏感词1", "敏感词2", "敏感词3")); SensitiveWordFilter filter = new SensitiveWordFilter(sensitiveWords); String text = "这是一段包含敏感词1和敏感词2的文本"; String filteredText = filter.filter(text); System.out.println(filteredText); // 这是一段包含******和******的文本 ``` 该示例中,SensitiveWordFilter类实现了敏感字体检测功能,构造函数接收一个敏感词列表,将其中的每个汇添加到Trie树中。filter方法接收一个文本,从文本的起点开始,依次将每个字符添加到Trie树中进行匹配,如果匹配到了一个敏感词,则将该敏感词替换为"*"。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值