,,Python实现敏感词过滤的4种方法

,,Python实现敏感词过滤的4种方法

本文主要介绍Python中过滤敏感词的四种方法,可以帮助你应对不和谐言论。感兴趣的朋友可以了解一下。

在我们生活中的一些场合,往往会出现一些不该出现的敏感词。我们一般用*来屏蔽,比如:尼玛-* *。有些骂人敏感词,有些政治敏感词,不应该出现在一些公共场合。这时候就需要一些手段来屏蔽这些敏感词。我来介绍一些敏感词屏蔽方法的简单版本。

(我已经尽力用图片的形式来做骂人的话了,否则文章不会发表)

方法一:replace过滤

Replace是最简单的字符串替换。当敏感词可能出现在一个字符串中时,我们可以直接使用相应的replace方法将敏感词替换为*。

缺点:

敏感词和文本少的时候还可以,多了就没效率了。

导入日期时间

now=datetime.datetime.now()

打印(过滤句子,' | ',现在)

如果有多个敏感词,可以用列表逐个替换。

为我在肮脏:

speak=speak.replace(i,' * ')

打印(现在说出' | ')

方法二:正则表达式过滤

正则表达式是一种很好的匹配方法。日常查询中经常用到正则表达式,包括我们的爬虫。这里主要用“|”来匹配。“|”表示从多个目标字符串中选择一个进行匹配。写一个简单的例子:

进口re

定义句子_过滤器(关键字,文本):

return re.sub('| ')。连接(关键字),' *** ',文本)

打印(句子_过滤器(脏,说话))

方法三:DFA过滤算法

DFA的算法,即确定性有限自动机算法,翻译成中文就是确定性有限自动机算法。其基本思想是基于状态转移检索敏感词,只需对待检测文本扫描一次,即可检测出所有敏感词。(有关实现,请参见代码注释)

#!/usr/bin/env python

# -*-编码:utf-8 -*-

# @时间:2020/4/15 11:40

# @软件:PyCharm

#文章_添加:https://www.cnblogs.com/JentZhang/p/12718092.html

__author__='JentZhang '

导入json

MinMatchType=1 #最小匹配规则

MaxMatchType=2 #最大匹配规则

DFAUtils类(对象):

'''

DFA算法

'''

def __init__(self,word_warehouse):

'''

算法初始化

:参数word_warehouse:同义词库

'''

#同义词库

self.root=dict()

#无意义词库,检测时需要跳过(这个无意义词最后在专门的地方维护,保存在数据库或其他存储介质中)

self.skip_root=[' ',' ','!', '!', '@', '#', '$', '', '*', '^', '%', '?', '?', '', '', ' 《", '》 ']

#初始化同义词库

对于word_warehouse中的word:

self.add_word(单词)

def add_word(self,word):

'''

添加同义词库

:参数字:

:返回:

'''

now_node=self.root

word_count=len(word)

对于范围内的I(字数):

char_str=word[i]

if char_str in now_node.keys():

#如果密钥存在,直接将其分配给下一个循环采集。

now_node=now_node.get(word[i])

now_node['is_end']=False

否则:

#如果字典不存在,就创建一个字典

new_node=dict()

If==word _ count-1: #最后一个

新节点['is_end']=真

Else: #不是最后一个

新节点['is_end']=假

现在节点[字符字符串]=新节点

现在节点=新节点

def check_match_word(self,txt,begin_index,match_type=MinMatchType):

'''

检查文本是否包含匹配字符。

:param txt:要检测的文本。

:param begin_index:调用getSensitiveWord获取单词的上界索引时输入的参数。

:param match_type:匹配规则1:最小匹配规则,2:最大匹配规则

:返回:如果存在,则返回匹配字符的长度;如果不存在,则返回0。

'''

标志=假

Match_flag_length=0 #匹配字符的长度。

现在_地图=self.root

Tmp_flag=0 #敏感词的长度,包括特殊字符

对于范围内的I(begin _ index,len(txt)):

word=txt[i]

#检查它是否是特殊字符'

如果单词在self.skip_root和len(现在_地图)100:

# len(nowMap)100保证已经找到这个词的开头之后出现的特殊字符

tmp_flag=1

继续

# 获取指定键

now_map=now_map.get(word)

如果现在_地图:#存在,则判断是否为最后一个

# 找到相应钥匙,匹配标识一

匹配标志长度=1

tmp_flag=1

# 如果为最后一个匹配规则,结束循环,返回匹配标识数

if now_map.get('is_end '):

# 结束标志位为真实的

标志=真

# 最小规则,直接返回,最大规则还需继续查找

if match_type==MinMatchType:

破裂

否则:#不存在,直接返回

破裂

如果tmp_flag 2或不标志:#长度必须大于等于1,为词

tmp_flag=0

返回tmp _标志

def get_match_word(self,txt,match_type=MinMatchType):

'''

获取匹配到的词语

:参数文本:待检测的文本

:param match_type:匹配规则1:最小匹配规则,2:最大匹配规则

:返回:文字中的相匹配词

'''

matched_word_list=list()

对于范围内的I(len(txt)):# 0-11

长度=self.check_match_word(txt,I,match_type)

如果长度为0:

word=txt[i:i长度]

matched_word_list.append(word)

# i=i长度- 1

返回匹配单词列表

def is_contain(self,txt,match_type=MinMatchType):

'''

判断文字是否包含敏感字符

:参数文本:待检测的文本

:param match_type:匹配规则1:最小匹配规则,2:最大匹配规则

:返回:若包含返回没错,否则返回错误的

'''

标志=假

对于范围内的I(len(txt)):

match _ flag=自我。检查_匹配_字(txt,I,匹配类型)

如果匹配标志为0:

标志=真

返回标志

def replace_match_word(self,txt,replace_char='* ',match_type=MinMatchType):

'''

替换匹配字符

:参数文本:待检测的文本

:param replace_char:用于替换的字符,匹配的敏感词以字符逐个替换,如'你是大王八,敏感词'王八,替换字符*,替换结果'你是大**'

:param match_type:匹配规则1:最小匹配规则,2:最大匹配规则

:返回:替换敏感字字符后的文本

'''

元组集=自身。获取匹配字(txt,match_type)

word_set=[i for i in tuple_set]

result_txt=' '

if len(word_set) 0: #如果检测出了敏感词,则返回替换后的文本

对于word_set中的单词:

replace _ string=len(word)* replace _ char

txt=txt.replace(word,replace_string)

结果_文本=文本

否则:#没有检测出敏感词,则返回原文本

结果_文本=文本

返回结果_txt

if __name__=='__main__ ':

DFA=DFA utils(word _ warehouse=word _ warehouse)

打印('词库结构:',json.dumps(dfa.root,确保_ascii=False))

# 待检测的文本

消息=消息

打印('是否包含:',dfa.is_contain(msg))

打印('相匹配的词:',dfa.get_match_word(msg))

打印('替换包含的词:',dfa.replace_match_word(msg))

方法四:AC自动机

交流电(交流电)自动机需要有前置知识:特里树(简单介绍:又称前缀树,字典树,是用于快速处理字符串的问题,能做到快速查找到一些字符串上的信息。)

详细参考:

https://www。洛古。com。cn/blog/juruohyfhaha/trie-Xue-Xi-宗-杰

交流电自动机,就是在疲劳树的基础上,增加一个失败指针,如果当前点匹配失败,则将指针转移到失败指针指向的地方,这样就不用回溯,而可以路匹配下去了。

详细匹配机制我在这里不过多赘述,关于交流电(交流电)自动机可以参考一下这篇文章:

https://www.jb51.net/article/128711.htm

大蟒可以利用ahocorasick模块快速实现:

# python3 -m pip安装pyahocorasick

进口ahocorasick

def build_actree(单词列表):

actree=ahocorasick .自动机()

对于索引,枚举中的单词(单词列表):

actree.add_word(word,(index,word))

actree.make_automaton()

退货行为

if __name__=='__main__ ':

actree=build _ actree(单词列表=单词列表)

sent_cp=已发送

对于actree.iter中的我(已发送):

sent _ CP=sent _ CP。替换(I[1][1],' ** ')

打印('屏蔽词:',i[1][1])

打印('屏蔽结果:',sent_cp)

当然,我们也可以手写一份交流电(交流电)自动机,具体参考:

类特里节点(对象):

__slots__=['value ',' next ',' fail ',' emit']

def __init__(self,value):

自我价值=价值

self.next=dict()

self.fail=无

self.emit=无

AhoCorasic类(对象):

__slots__=['_root']

def __init__(self,words):

自我. root=AhoCorasic ._build_trie(单词)

@静态方法

定义_构建_trie(单词):

断言isinstance(单词,列表)和单词

root=TrieNode('root ')

逐字逐句:

节点=根

对于单词中的丙:

如果c不在node.next中:

node.next[c]=TrieNode(c)

node=node.next[c]

如果不是节点发出:

node.emit={word}

否则:

node.emit.add(word)

队列=[]

queue.insert(0,(根,无))

而len(队列)0:

node_parent=queue.pop()

curr,parent=node_parent[0],node_parent[1]

for sub in curr.next.itervalues():

queue.insert(0,(sub,curr))

如果父项为无:

继续

否则如果父项是根:

curr.fail=root

否则:

失败=父级。失败

当失败且当前值不在失败中时。下一步:

失败=失败。失败

如果失败:

curr。失败=失败。下一个[货币值]

否则:

curr.fail=root

返回根目录

定义搜索(自身,秒):

seq_list=[]

节点=自身. root

对于枚举中的I、c:

匹配=真

而c不在node.next中:

如果不是节点失败:

匹配=假

节点=自身. root

破裂

节点=节点。失败

如果不匹配:

继续

node=node.next[c]

if node.emit:

for _ in node.emit:

from_index=i 1 - len(_)

match_info=(from_index,_)

序列列表附加(匹配信息)

节点=自身. root

返回序列列表

if __name__=='__main__ ':

aho=AhoCorasic(['foo ',' bar'])

打印Aho。搜索(' barfoothefoobarman ')

以上便是使用计算机编程语言实现敏感词过滤的四种方法,前面两种方法比较简单,后面两种偏向算法,需要先了解算法具体实现的原理,之后代码就好懂了(DFA作为比较常用的过滤手段,建议大家掌握一下~)

最后附上敏感词词库:

https://github.com/qloog/sensitive_words

以上就是计算机编程语言实现敏感词过滤的四种方法的详细内容,更多关于大蟒敏感词过滤的资料请关注我们其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: