基于DFA算法的敏感词过滤
Posted bowenqianngzhibushiwo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于DFA算法的敏感词过滤相关的知识,希望对你有一定的参考价值。
DFA算法的全称是Deterministic Finite Automaton,即确定有穷永动机算法。
DFA算法中对汉字的存储,字典树中的节点存储的字符Character类型,不是ASCII码。
建立默认敏感词替换词
private sttaic final String REPLACE=" whatever";
定义字典树
字典树中的节点拥有以下属性:
1.kv键值对类型的子节点,key中保存着敏感词,v是triedNode类型的保存节点
2.代表分支结尾的end属性
3.给字典树的分支添加end的方法
4 获取节点中的key的方法
5判断是否到达end节点的方法
6 添加子节点的方法
public class TrieNode{
标定敏感词的结尾 true为关键词终结,false为继续
private boolean end= false;
/*
key 是下一个字符,value是对应的节点 ,subNode中保存了子节点的值和子节点的位置
/
private Map<Character,TriedNode> subNodes=new HashMap<>();
/**
向指定位置添加节点树
*/
void addSubNode(Character Key,TriedNode node){subNodes,put(key,node);}
//获取下一个节点
TriedNode getsubNode(Character key){return subNodes.get(key);}
boolean isKeywordEnd(){return end;}
void setKeyEnd(booleean end){this.end=end;}
public int getSubNodeCount(){return subNodes.size();}
}
创建空节点作为字典树的根
private TriedNode root=new TriedNode();
//判断输入的内容是否是无意义的符号
boolean isSymbol(char c){
int ic=(int)c;
//0x2e80-0x9ff东亚文字范围
return !CharUtil.iisAsciiAlphanumeric(c)&&(ic<0x2e80||ic>0x9ff);
}
/**
过滤敏感词
*/
首先判断输入内容是否为空 用StringUtils.isBlank()来判断,为空就return 输入的字符串
定义结果 StringBuffer result 将判断的结果都存入StringBuffer
int begin=0;//回滚数
int position=0;//当前的比较位置
public String filter(String text){
TriedNode rootT=root;
StringBuffer sb=new StringBuffer();
int begin=0;
int position=0;
while(begin<tex.length()){
char c=-tex.charAt(position);
//空格直接跳过
if(isSymbol(c)){
if(rootT==root){
sb.append(c);
beigin++;
}
position++;
continue;
}
rootT=rootT.getSubNode(c);
if(rootT==null){
sb.append(c);
posiotn=begin++;
}else if (tempNode.isKeywordEnd()) {
// 发现敏感词, 从begin到position的位置用replacement替换掉
sbt.append(replacement);
position = position + 1;
begin = position;
tempNode = rootNode;
} else {
++position;
}
}
result.append(text.substring(begin));
return sbt.toString();
}
private void addWord(String lineTxt) {
TrieNode tempNode = rootNode;
// 循环每个字节
for (int i = 0; i < lineTxt.length(); ++i) {
Character c = lineTxt.charAt(i);
// 过滤空格
if (isSymbol(c)) {
continue;
}
TrieNode node = tempNode.getSubNode(c);
if (node == null) { // 没初始化
node = new TrieNode();
tempNode.addSubNode(c, node);
}
tempNode = node;
if (i == lineTxt.length() - 1) {
// 关键词结束, 设置结束标志
tempNode.setKeywordEnd(true);
}
}
}
}
}
public void afterPropertiesSet() throws Exception {
rootNode = new TrieNode();
try {
InputStream is = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("SensitiveWords.txt");
InputStreamReader read = new InputStreamReader(is);
BufferedReader bufferedReader = new BufferedReader(read);
String lineTxt;
while ((lineTxt = bufferedReader.readLine()) != null) {
lineTxt = lineTxt.trim();
addWord(lineTxt);
}
read.close();
} catch (Exception e) {
logger.error("读取敏感词文件失败" + e.getMessage());
}
}
}
以上是关于基于DFA算法的敏感词过滤的主要内容,如果未能解决你的问题,请参考以下文章