浅谈Python 敏感词过滤的实现


Posted in Python onAugust 15, 2019

一个简单的实现

class NaiveFilter():

  '''Filter Messages from keywords

  very simple filter implementation

  >>> f = NaiveFilter()
  >>> f.add("sexy")
  >>> f.filter("hello sexy baby")
  hello **** baby
  '''

  def __init__(self):
    self.keywords = set([])

  def parse(self, path):
    for keyword in open(path):
      self.keywords.add(keyword.strip().decode('utf-8').lower())

  def filter(self, message, repl="*"):
    message = str(message).lower()
    for kw in self.keywords:
      message = message.replace(kw, repl)
    return message

其中strip() 函数 删除附近的一些空格,解码采用utf-8的形式,然后将其转为小写。

parse()函数就是打开文件,然后从中取各个关键词,然后将其存在关键词集合中。

filter()函数是一个过滤器函数,其中将消息转化为小写,然后将关键词替换成*。、

class BSFilter:

  '''Filter Messages from keywords

  Use Back Sorted Mapping to reduce replacement times

  >>> f = BSFilter()
  >>> f.add("sexy")
  >>> f.filter("hello sexy baby")
  hello **** baby
  '''

  def __init__(self):
    self.keywords = []
    self.kwsets = set([])
    self.bsdict = defaultdict(set)
    self.pat_en = re.compile(r'^[0-9a-zA-Z]+$') # english phrase or not

  def add(self, keyword):
    if not isinstance(keyword, str):
      keyword = keyword.decode('utf-8')
    keyword = keyword.lower()
    if keyword not in self.kwsets:
      self.keywords.append(keyword)
      self.kwsets.add(keyword)
      index = len(self.keywords) - 1
      for word in keyword.split():
        if self.pat_en.search(word):
          self.bsdict[word].add(index)
        else:
          for char in word:
            self.bsdict[char].add(index)

  def parse(self, path):
    with open(path, "r") as f:
      for keyword in f:
        self.add(keyword.strip())

  def filter(self, message, repl="*"):
    if not isinstance(message, str):
      message = message.decode('utf-8')
    message = message.lower()
    for word in message.split():
      if self.pat_en.search(word):
        for index in self.bsdict[word]:
          message = message.replace(self.keywords[index], repl)
      else:
        for char in word:
          for index in self.bsdict[char]:
            message = message.replace(self.keywords[index], repl)
    return message

在上面的实现例子中,对于搜索查找进行了优化,对于英语单词,直接进行了按词索引字典查找。对于其他语言模式,我们采用逐字符查找匹配的一种模式。

BFS:宽度优先搜索方式。

class DFAFilter():

  '''Filter Messages from keywords

  Use DFA to keep algorithm perform constantly

  >>> f = DFAFilter()
  >>> f.add("sexy")
  >>> f.filter("hello sexy baby")
  hello **** baby
  '''

  def __init__(self):
    self.keyword_chains = {}
    self.delimit = '\x00'

  def add(self, keyword):
    if not isinstance(keyword, str):
      keyword = keyword.decode('utf-8')
    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:
        if not isinstance(level, dict):
          break
        for j in range(i, len(chars)):
          level[chars[j]] = {}
          last_level, last_char = level, chars[j]
          level = level[chars[j]]
        last_level[last_char] = {self.delimit: 0}
        break
    if i == len(chars) - 1:
      level[self.delimit] = 0

  def parse(self, path):
    with open(path,encoding='UTF-8') as f:
      for keyword in f:
        self.add(keyword.strip())

  def filter(self, message, repl="*"):
    if not isinstance(message, str):
      message = message.decode('utf-8')
    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
      else:
        ret.append(message[start])
      start += 1

    return ''.join(ret)

DFA即Deterministic Finite Automaton,也就是确定有穷自动机。

使用了嵌套的字典来实现。

参考

Github:敏感词过滤系统

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python进阶教程之循环对象
Aug 30 Python
python使用logging模块发送邮件代码示例
Jan 18 Python
基于python实现简单日历
Jul 28 Python
基于腾讯云服务器部署微信小程序后台服务(Python+Django)
May 08 Python
Python多线程Threading、子线程与守护线程实例详解
Mar 24 Python
Python MOCK SERVER moco模拟接口测试过程解析
Apr 13 Python
python 异步async库的使用说明
May 04 Python
python语言的优势是什么
Jun 17 Python
Python QT组件库qtwidgets的使用
Nov 02 Python
Python接口自动化系列之unittest结合ddt的使用教程详解
Feb 23 Python
Jupyter notebook 不自动弹出网页的解决方案
May 21 Python
什么是Python装饰器?如何定义和使用?
Apr 11 Python
pycharm创建scrapy项目教程及遇到的坑解析
Aug 15 #Python
通过selenium抓取某东的TT购买记录并分析趋势过程解析
Aug 15 #Python
Python依赖包整体迁移方法详解
Aug 15 #Python
使用python批量修改文件名的方法(视频合并时)
Mar 24 #Python
python 修改本地网络配置的方法
Aug 14 #Python
python django 原生sql 获取数据的例子
Aug 14 #Python
django 连接数据库 sqlite的例子
Aug 14 #Python
You might like
php 分库分表hash算法
2009/11/12 PHP
php将图片保存入mysql数据库失败的解决方法
2014/12/27 PHP
php基于session锁防止阻塞请求的方法分析
2017/08/07 PHP
Javascript模板技术
2007/04/27 Javascript
JS中动态添加事件(绑定事件)的代码
2011/01/09 Javascript
JS下拉框内容左右移动效果的具体实现
2013/07/10 Javascript
关于动态执行代码(js的Eval)实例详解
2016/08/15 Javascript
详谈JavaScript的闭包及应用
2017/01/17 Javascript
详谈jQuery Ajax(load,post,get,ajax)的用法
2017/03/02 Javascript
nodejs express配置自签名https服务器的方法
2018/05/22 NodeJs
Vue.js项目中管理每个页面的头部标签的两种方法
2018/06/25 Javascript
vue 界面刷新数据被清除 localStorage的使用详解
2018/09/16 Javascript
VUE 解决mode为history页面为空白的问题
2019/11/01 Javascript
vue element-ui实现动态面包屑导航
2019/12/23 Javascript
Vue实现附件上传功能
2020/05/28 Javascript
[03:24][TI9纪实] Dota奶爸
2019/08/22 DOTA
实例讲解Python中SocketServer模块处理网络请求的用法
2016/06/28 Python
使用Python中的tkinter模块作图的方法
2017/02/07 Python
Sanic框架异常处理与中间件操作实例分析
2018/07/16 Python
更改Python的pip install 默认安装依赖路径方法详解
2018/10/27 Python
Python 使用xlwt模块将多行多列数据循环写入excel文档的操作
2020/11/10 Python
YSL Beauty加拿大官方商城:圣罗兰美妆加拿大
2017/05/15 全球购物
教育学专业毕业生的自我鉴定
2013/11/26 职场文书
迟到检讨书1000字
2014/01/15 职场文书
小学国庆节活动方案
2014/02/11 职场文书
学生安全教育材料
2014/02/14 职场文书
体育课课后反思
2014/04/24 职场文书
高中教师评语大全
2014/04/25 职场文书
分公司任命书
2014/06/06 职场文书
行政秘书工作自我鉴定
2014/09/15 职场文书
写景作文评语集锦
2014/12/25 职场文书
详解PHP Swoole与TCP三次握手
2021/05/27 PHP
redis cluster支持pipeline的实现思路
2021/06/23 Redis
企业开发CSS命名BEM代码规范实践
2022/02/12 HTML / CSS
Nginx本地配置SSL访问的实例教程
2022/05/30 Servers
css中:last-child不生效的解决方法
2022/08/05 HTML / CSS