欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

敏感词过滤

程序员文章站 2022-07-12 18:52:41
...

帖子发布

敏感词过滤

html便签过滤
● 这个其实就是调用函数就ok了,做的也就是将HTML的关键词给转义掉;
question.setContent(HtmlUtils.htmlEscape(question.getContent()));

敏感词与前缀树
● 重点就是这个部分了啦
● 前缀树的结构:会持有一个map或者一个数组表明它有那些子节点,然后判断敏感词是不是能够继续,另外就是是否为关键词,这里的布尔值有局限性,就是当一个字符串为另一个的前缀时,不过这也取决于我们的文本是如何写的;简单的方法是结尾结点保存沿途字符所构成的字符串
private class TrieNode {
//是否为关键词结尾的结点
private boolean end = false;
//前缀树中的一个结点持有一个map,这个map中就是当前结点的子结点
private Map<Character, TrieNode> subNodes = new HashMap<Character, TrieNode>();

    //增加子节点
    public void addSubNode(Character key, TrieNode node) {
        subNodes.put(key, node);
    }

    //得到子节点
    TrieNode getSubNode(Character key) {
        return subNodes.get(key);
    }
    //判断是否为结尾节点
    boolean isKeyWordEnd() {
        return end;
    }
    //设置为结尾结点
    void setKeyWord(boolean end) {
        this.end = end;
    }
}

● 增加敏感词的函数,其实还是蛮容易懂得了
/**
* 增加关键字的结点
* 每次从lineText中读一个字符。然后查询当前结点下有没有这个字符
* 如果没有就创建一下,然后当前指针向下移动
* 如果lineText走到最后,说明为结尾结点
* @param lineText
*/
private void addWord(String lineText) {
TrieNode temp = rootNode;
for (int i = 0; i < lineText.length(); i++) {
Character c = lineText.charAt(i);
TrieNode node = temp.getSubNode©;
if (node == null) {
node = new TrieNode();
temp.addSubNode(c, node);
}
temp = node;
if (i == lineText.length() - 1) {
temp.setKeyWord(true);
}
}
}
● 过滤函数
//判断是否为故意扰乱敏感词的字符
private boolean isSymbol(char c) {
int ic = (int) c;
//东亚文字
return !CharUtils.isAsciiAlphanumeric© && (ic < 0x2E80 || ic > 0x9FFF);
}

/**
 * 用来过滤的函数
 * @param text
 * @return
 */
public String filter(String text) {
    if (StringUtils.isBlank(text)) {
        return text;
    }
    StringBuilder result = new StringBuilder();
    String replaceMent = "***";
    TrieNode tempNode = rootNode;
    //begin一直向后移动,代表当前搜索的敏感词的头结点
    int begin = 0;
    //position是当前敏感词的某一个结点,来回移动的那个
    int position = 0;

    while (position < text.length()) {
        char c = text.charAt(position);
        if (isSymbol(c)) {
            //如果还在rootNode,说明还没进前缀树,
            //这部分奇怪的字符直接加进来就好
            //否则就跳过,只找那些关键字过滤
            if (tempNode == rootNode) {
                result.append(c);
                begin++;
            }
            position++;
            continue;
        }
        tempNode = tempNode.getSubNode(c);
        //当前结点为null,说明不是敏感词
        if (tempNode == null) {
            result.append(text.charAt(begin));
            position = begin + 1;
            begin = position;
            tempNode = rootNode;
        } else if (tempNode.isKeyWordEnd()) {
            result.append(replaceMent);
            position = position + 1;
            begin = position;
            tempNode = rootNode;
        } else {
            ++position;
        }
    }
    //position走到了最后,别忘了把begin剩下的也加进来,
    //不过也有可能begin也没有啥嘞
    result.append(text.substring(begin));
    return result.toString();
}