浅谈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发送各类邮件的主要方法
Dec 22 Python
神经网络python源码分享
Dec 15 Python
Pandas中把dataframe转成array的方法
Apr 13 Python
pandas 选择某几列的方法
Jul 03 Python
Windows 64位下python3安装nltk模块
Sep 19 Python
Python GUI学习之登录系统界面篇
Aug 21 Python
python爬虫 2019中国好声音评论爬取过程解析
Aug 26 Python
python爬虫开发之使用python爬虫库requests,urllib与今日头条搜索功能爬取搜索内容实例
Mar 10 Python
Django实现whoosh搜索引擎使用jieba分词
Apr 08 Python
pyCharm 实现关闭代码检查
Jun 09 Python
django rest framework 自定义返回方式
Jul 12 Python
Scrapy-Redis之RedisSpider与RedisCrawlSpider详解
Nov 18 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
JAVA/JSP学习系列之六
2006/10/09 PHP
一段防盗连的PHP代码
2006/12/06 PHP
php中mkdir函数用法实例分析
2014/11/15 PHP
PHP 实现从数据库导出到.csv文件方法
2017/07/06 PHP
ThinkPHP框架中使用Memcached缓存数据的方法
2018/03/31 PHP
有一段有意思的代码-javascript现实多行信息
2007/08/26 Javascript
Prototype String对象 学习
2009/07/19 Javascript
在一个浏览器里呈现所有浏览器测试结果的前端测试工具的思路
2010/03/02 Javascript
深入理解javascript原型链和继承
2014/09/23 Javascript
JavaScript更改原始对象valueOf的方法
2015/03/19 Javascript
JavaScript截取指定长度字符串点击可以展开全部代码
2015/12/04 Javascript
jQuery解决$符号命名冲突
2016/06/18 Javascript
Javascript 获取鼠标当前的位置实现方法
2016/10/27 Javascript
jsTree使用记录实例
2016/12/01 Javascript
深入浅析Nodejs的Http模块
2017/06/20 NodeJs
JavaScript注册时密码强度校验代码
2017/06/30 Javascript
微信小程序中使用Promise进行异步流程处理的实例详解
2017/08/17 Javascript
template.js前端模板引擎使用详解
2017/10/10 Javascript
微信小程序实现页面跳转传值以及获取值的方法分析
2017/12/18 Javascript
JavaScript 作用域实例分析
2019/10/02 Javascript
简单介绍Python下自己编写web框架的一些要点
2015/04/29 Python
python获取当前日期和时间的方法
2015/04/30 Python
简单的python后台管理程序
2017/04/13 Python
Python2.7编程中SQLite3基本操作方法示例
2017/08/09 Python
机器学习的框架偏向于Python的13个原因
2017/12/07 Python
Python编程深度学习绘图库之matplotlib
2018/12/28 Python
Python编程中类与类的关系详解
2019/08/08 Python
家长给幼儿园的表扬信
2014/01/09 职场文书
优秀护士演讲稿
2014/04/30 职场文书
2014年教师批评与自我批评思想汇报
2014/09/20 职场文书
毕业生银行实习自我鉴定
2014/10/14 职场文书
无子女夫妻离婚协议书(4篇)
2014/10/20 职场文书
八达岭长城导游词
2015/01/30 职场文书
2015年体育部工作总结
2015/04/02 职场文书
工作态度不好检讨书
2015/05/06 职场文书
漫画「古见同学有交流障碍症」第25卷封面公开
2022/03/21 日漫