DFA算法过滤敏感词(直拿直用)
·
'''
DFA算法过滤敏感词
'''
'''
DFA敏感词存放结构(公用前缀)
{
's': {
'e': {
'x': {
'y': {
'\x00': 0
}
}
}
},
'h': {
'e': {
'l': {
'l': {
'o': {
'\x00': 0
}
},
'p': {
'\x00': 0,
'l': {
'i': {
'n': {
'e': {
'\x00': 0
}
}
}
}
}
}
}
}
}
'''
import pickle
class DFAFilter():
def __init__(self):
# 存放敏感词的字典
self.keyword_chains = {}
# 设置分隔符为 '\x00',用于在特定场合下作为字符串的分隔标志
self.delimit = '\x00'
def add(self, keyword):
"""
将给定的敏感词添加到敏感词链中。
:param keyword: 需要添加的关键词,将被转换为小写并去除首尾空白。
:return: 无返回值。
"""
# keyword = keyword.lower() # 将敏感词转换为小写
chars = keyword.strip() # 去除敏感词的首尾空白字符
if not chars: # 如果处理后的敏感词为空,则直接返回
return
level = self.keyword_chains # 初始化根级别
# 遍历敏感词中的每个字符,逐级向下创建或更新字典结构
for i in range(len(chars)):
# 如果字符在当前级别存在,说明可以公用,进入下一级
if chars[i] in level:
level = level[chars[i]]
# 如果不存在,从当前位置创建所有缺失级别到敏感词末尾
else:
for j in range(i, len(chars)):
level[chars[j]] = {}
last_level, last_char = level, chars[j]
level = level[chars[j]]
# 在最后一个创建的级别中,添加一个以self.delimit为键,值为0的项
last_level[last_char] = {self.delimit: 0}
break
# 如果遍历到了关键词的末尾,则在当前级别添加一个以self.delimit为键,值为0的项
if i == len(chars) - 1:
level[self.delimit] = 0
def parse(self, path):
if path.endswith('pkl'):
with open(path, "rb") as f:
data = pickle.load(f)
for keyword in data:
self.add(keyword.strip())
else:
with open(path, "r", encoding='utf-8') as f:
for keyword in f:
self.add(keyword.strip())
def filter(self, path, repl="*"):
"""
过滤给定消息中的敏感关键词,用指定字符替换。
参数:
- message: 待过滤的字符串消息。
- repl: 用于替换敏感词的字符,默认为"*"。
返回值:
- 过滤后的字符串。
"""
with open(path, mode='r', encoding='utf-8') as f:
message = f.read()
# message = message.lower()
ret = [] # 存储过滤后的字符
start = 0 # 指向当前处理的字符位置
while start < len(message):
level = self.keyword_chains # 初始化敏感词层级
step_ins = 0 # 记录当前嵌套层级
for char in message[start:]:
if char in level:
step_ins += 1
if self.delimit not in level[char]:
level = level[char]
else:
# 当遇到分隔符时,添加替换字符到结果中,并调整起始位置
ret.append(repl * step_ins)
start += step_ins - 1
break
else:
# 当字符不在关键词列表中,添加原字符到结果中,并结束当前循环
ret.append(message[start])
break
start += 1 # 更新起始位置
f.close()
return ''.join(ret) # 将结果列表转换为字符串并返回
'''
将过滤敏感词之后的message重新sink
'''
def outputNoSensitiveness(self, outputPath, inputMessage):
filterSensitiveness = open(outputPath, 'w')
filterSensitiveness.write(inputMessage)
filterSensitiveness.close()
if __name__ == '__main__':
dfa = DFAFilter()
dfa.parse('data.pkl')
# dfa.parse('C:\job\AI数据集平台工具\数据\sensitive_words.txt')
print(f"敏感词字典为:{dfa.keyword_chains}")
later_filter = dfa.filter('C:\job\AI数据集平台工具\数据\DFA.txt')
print(f"敏感词过滤后的结果为:{later_filter}")
output = dfa.outputNoSensitiveness('C:\job\AI数据集平台工具\数据\\fliter_sensitiveness.txt', later_filter)
附:敏感词关键字.pkl方式创建代码,以下:
import pickle
if __name__ == '__main__':
# 创建一个字典对象
data = ['flink', 'spark', 'hive', 'FLINK', 'SPARK', 'HIVE', '实时', '离线']
# 打开一个文件用于写入
with open('data.pkl', 'wb') as f:
# 使用pickle.dump()将字典对象序列化并保存到文件中
pickle.dump(data, f)
附:过滤消息样本数据,以下:
flink是一个实时计算引擎,flink处理时间为毫秒级别。
flink采用流的模式读取数据
flink使用事件时间而不是spark的处理时间
flink通过窗口进行聚合计算,checkpoint是flink的核心容错机制,其通过快照的方式定期将各个operator的状态存储下来,checkpoint设置的越大,小文件越少
flink通过watermark水位线处理延迟和乱序数据,是flink为了处理eventtime提出的新的机制,侧输出流sideoutput是针对超过了最大允许的延迟时间的最后兜底机制...
SPARK是离线计算引擎
SPARK使用处理时间作为时间语义
SPARK是批处理,也有近似实时的微批处理,spark处理时间为秒级别的
hive是离线数仓
hive用于处理离线数据,时间为T-1
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)