敏感词检测
题记
本文主要用于记录如何在go中使用敏感词检测和对底层源码的分析。主要参考的GitHub仓库是:github.com/feiin/sensitivewords。
用法
1 | package main |
这是一个实例,来展示Go如何使用敏感词检测技术。
底层源码剖析
该图片是本文仓库的文件目录。
在这里我们主要是分析trie.go文件。
keywords.txt主要是敏感词测试文件
1 | 卧槽 |
doc.go里面没有代码
example_test.go,sensitive_words_test.go,trie_test.go,这些均为测试代码,我们不做分析处理。
sensitive_words.go文件主要是实例化一个敏感词库,加载敏感词库的文件(keywords.txt)并调用Add方法添加到敏感词库中。对我们了解敏感词检测的实现意义不大。我们不做多的学习。
trie.go是我们接下来主要要探究的部分。
1 | //TrieTree Trie树 |
首先定义了两个结构体:TrieTree和TrieNode。TrieTree表示整个Trie树,其中包含一个指向根节点的指针Root。TrieNode表示树中的节点,其中包含一个布尔值IsEnd用于标识当前节点是否为一个敏感词的结束节点,以及一个Children映射表,用于存储当前节点的子节点。
接下来定义了NewTrieTree函数,用于创建一个新的TrieTree对象。该函数会初始化根节点,并返回TrieTree对象的指针。
1 | //Add 添加敏感词 |
该方法接收一个字符串参数 word
,表示要添加的敏感词。首先,通过检查 word
是否为空字符串,如果为空,则直接返回,不执行任何操作。然后,定义一个指针变量 treeNode
,指向 Trie 树的根节点 tree.Root
,用于表示当前节点。将要添加的敏感词 word
转换为一个 rune
类型的切片 treeWords
,方便按字符遍历敏感词。然后,定义一个指针变量 current
,指向当前节点 treeNode
,用于表示当前遍历的节点。接下来,通过 for
循环遍历敏感词的每个字符。在每次循环中,将当前字符存储在 word
变量中。通过检查当前节点的 Children
字段,判断当前字符是否已经是当前节点的子节点之一。如果是,则更新 current
为当前字符对应的子节点。如果当前字符不是当前节点的子节点,则表示该字符还未在当前节点的子节点中,需要创建一个新的节点。创建一个新的节点 newNode
,设置其 IsEnd
字段为 false
,并初始化其 Children
字段为一个空的 map[rune]*TrieNode
。将新节点 newNode
添加到当前节点 current
的 Children
字段中,键为当前字符 word
。然后,将 current
更新为新添加的节点 newNode
,以便继续遍历敏感词的下一个字符。循环结束后,表示敏感词的所有字符都已经遍历完毕。将最后一个字符对应的节点 current
的 IsEnd
字段设置为 true
,表示该节点是敏感词的结尾节点。
AddWords函数本质上就是调用Add方法。
1 | //Filter 过滤敏感词为* |
1 | //Find 查找敏感词,找到第一个就退出 |
该方法接收一个字符串参数 input
,表示要进行敏感词查找的输入文本。首先,将输入文本 input
转换为一个 rune
类型的切片 words
,方便按字符遍历文本。然后,定义变量 current
(指向当前节点)、found
(表示是否找到字符)、treeNode
(指向 Trie 树的根节点)、offset
(表示当前遍历的字符偏移量)。通过一个 for
循环遍历输入文本的每个字符。在每次循环中,将当前字符存储在变量 w
中。通过检查当前节点的 Children
字段,判断当前字符是否是当前节点的子节点之一。如果是,则更新 current
为当前字符对应的子节点,并将 found
设置为 true
。如果当前字符不是当前节点的子节点,则表示该字符不在当前节点的子节点中,需要进行回溯。将循环索引 i
减去偏移量 offset
,以回退到上一个已匹配的位置。将偏移量 offset
重置为 0,表示回退后的位置。将当前节点 treeNode
更新为 Trie 树的根节点,以重新开始匹配过程。循环结束后,表示整个文本已经遍历完毕。如果最后一个字符对应的节点 current
是敏感词的结尾节点(current.IsEnd
为 true
),则表示找到了敏感词。此时,返回结果为 true
和找到的敏感词,即 string(words[i-offset : i+1])
。如果循环结束时没有找到敏感词,则返回结果为 false
和一个空字符串。通过上述操作,方法可以在输入文本中查找敏感词,并返回是否找到敏感词以及找到的第一个敏感词。请注意,此方法只会找到第一个敏感词并立即退出,而不会继续查找其他可能存在的敏感词。
FindAll函数本质上就是定义了一个[]string类型
的results
,每次找到敏感词就append进results。
FindAny函数本质上就是定义了一个[]string类型
的results
,每次找到敏感词就append进results,只不过他会判断len(result)==count
。
- 标题: 敏感词检测
- 作者: Olivia的小跟班
- 创建于 : 2023-06-19 19:39:10
- 更新于 : 2023-06-20 00:57:28
- 链接: https://www.youandgentleness.cn/2023/06/19/敏感词检测/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。