文本字符串的快速多关键字搜索引擎

acora的Python项目详细描述


What is Acora?

acora是python的“fgrep”,python是一个快速的多关键字文本搜索引擎。

基于一组关键字和 Aho-Corasick algorithm, 它生成一个搜索自动机,并在字符串输入上运行,可以是unicode 或字节。

acora提供了纯python实现和快速二进制文件 用cython编写的模块。但是,请注意当前的构造 算法不适用于非常大的关键字集(即 比几千块还多)。

你可以找到latest source code 在Github上。

要报告错误或请求新功能,请使用github bug tracker。请尝试提供 在不需要太多要求的情况下复制问题的短测试用例 实验或大量数据。越容易 再现问题,越容易解决。

Features

  • 适用于Unicode字符串和字节字符串
  • 对于大多数输入,大约是python正则表达式引擎的2-3倍
  • 查找重叠匹配项,即所有关键字的所有匹配项
  • 支持不区分大小写的搜索(~10倍于're')
  • 搜索时释放gil
  • 附加的(慢但短)纯python实现
  • 支持Python2.5+和3.x
  • 支持在文件中搜索
  • 许可的BSD许可证

How do I use it?

导入包:

>>> from acora import AcoraBuilder

收集一些关键字:

>>> builder = AcoraBuilder('ab', 'bc', 'de')
>>> builder.add('a', 'b')

或:

>>> builder.update(['a', 'b'])  # new in version 2.0

为当前关键字集生成acora搜索引擎:

>>> ac = builder.build()

在字符串中搜索所有匹配项:

>>> ac.findall('abc')
[('a', 0), ('ab', 0), ('b', 1), ('bc', 1)]
>>> ac.findall('abde')
[('a', 0), ('ab', 0), ('b', 1), ('de', 2)]

在搜索结果传入时对其进行迭代:

>>> for kw, pos in ac.finditer('abde'):
...     print("%2s[%d]" % (kw, pos))
 a[0]
ab[0]
 b[1]
de[2]

acora还直接支持解析文件(二进制模式):

>>> keywords = ['Import', 'FAQ', 'Acora', 'NotHere'.upper()]

>>> builder = AcoraBuilder([s.encode('ascii') for s in keywords])
>>> ac = builder.build()

>>> found = set(kw for kw, pos in ac.filefind('README.rst'))
>>> len(found)
3

>>> sorted(str(s.decode('ascii')) for s in found)
['Acora', 'FAQ', 'Import']

FAQs and recipes

  1. 如何贪婪地搜索最长的匹配关键字?

    >>> builder = AcoraBuilder('a', 'ab', 'abc')
    >>> ac = builder.build()
    
    >>> for kw, pos in ac.finditer('abbabc'):
    ...     print(kw)
    a
    ab
    a
    ab
    abc
    
    >>> from itertools import groupby
    >>> from operator import itemgetter
    
    >>> def longest_match(matches):
    ...     for pos, match_set in groupby(matches, itemgetter(1)):
    ...         yield max(match_set)
    
    >>> for kw, pos in longest_match(ac.finditer('abbabc')):
    ...     print(kw)
    ab
    abc
    

    注意,这个配方假设搜索词没有 与前缀重叠。

  2. 如何逐行解析任意行尾?

    >>> def group_by_lines(s, *keywords):
    ...     builder = AcoraBuilder('\r', '\n', *keywords)
    ...     ac = builder.build()
    ...
    ...     current_line_matches = []
    ...     last_ending = None
    ...
    ...     for kw, pos in ac.finditer(s):
    ...         if kw in '\r\n':
    ...             if last_ending == '\r' and kw == '\n':
    ...                 continue # combined CRLF
    ...             yield tuple(current_line_matches)
    ...             del current_line_matches[:]
    ...             last_ending = kw
    ...         else:
    ...             last_ending = None
    ...             current_line_matches.append(kw)
    ...     yield tuple(current_line_matches)
    
    >>> kwds = ['ab', 'bc', 'de']
    >>> for matches in group_by_lines('a\r\r\nbc\r\ndede\n\nab', *kwds):
    ...     print(matches)
    ()
    ()
    ('bc',)
    ('de', 'de')
    ()
    ('ab',)
    
  3. 如何像fgrep那样找到包含关键字的整行?

    >>> def match_lines(s, *keywords):
    ...     builder = AcoraBuilder('\r', '\n', *keywords)
    ...     ac = builder.build()
    ...
    ...     line_start = 0
    ...     matches = False
    ...     for kw, pos in ac.finditer(s):
    ...         if kw in '\r\n':
    ...             if matches:
    ...                  yield s[line_start:pos]
    ...                  matches = False
    ...             line_start = pos + 1
    ...         else:
    ...             matches = True
    ...     if matches:
    ...         yield s[line_start:]
    
    >>> kwds = ['x', 'de', '\nstart']
    >>> text = 'a line with\r\r\nsome text\r\ndede\n\nab\n start 1\nstart\n'
    >>> for line in match_lines(text, *kwds):
    ...     print(line)
    some text
    dede
    start
    

Changelog

  • 2.2【2018-08-16】
    • 更新以使用cython 0.29构建cpython 3.7。
  • 2.1【2017-12-15】
    • 修复对空引擎的处理(Github问题18)
  • 2.0【2016-03-17】
    • 重写构造算法以加快速度并节省内存
  • 1.9【2015-10-10】
    • 使用cython 0.23.4重新编译,以便更好地与最近的 python版本。
  • 1.8【2014-02-12】
    • 对预构建搜索引擎的pickle支持
    • Builder中的性能优化
    • Unicode解析针对Python3.3及更高版本进行了优化
    • 安装cython后不再重新编译源,除非 --with-cython选项传递给setup.py(需要cython 0.20+)
    • 最新cython版本的生成失败
    • 使用cython 0.20.1构建
  • 1.7【2011-08-24】
    • 在二进制字符串中搜索字节值时>;127已断开
    • 使用cython 0.15+
    • 构建
  • 1.6【2011-07-24】
    • 大大加快了自动生成速度
    • 不再在源分布中包含.hg repo
    • 使用cython 0.15(rc0)构建
  • 1.5[2011-01-24]
    • cython编译的nfa-2-dfa结构运行速度大大加快
    • 即使未安装cython,也始终构建扩展模块
    • --no-compilesetup.py中切换以防止扩展模块生成
    • 使用cython 0.14.1(rc2)构建
  • 1.4[2009-02-10]
    • 在内部搜索引擎循环中小幅加速
    • 一些代码清理
    • 建成使用cython 0.12.1(最终版)
  • 1.3[2009-01-30]
    • 文件搜索的主要修复程序
    • 使用cython 0.12.1(beta0)构建
  • 1.2[2009-01-30]
    • 对acorabuilder类的深度复制支持
    • 文档/测试修复程序
    • 在源代码分布中包含.hg repo
    • 使用cython 0.12.1(beta0)构建
  • 1.1[2009-01-29]
    • 文档更新
    • 一些清理
    • 使用cython 0.12.1(beta0)构建
  • 1.0【2009-01-29】
    • 初始版本

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
分离实体上的java JPA merge()在其存在时进行插入   java Android Javamail自定义身份验证   java如何找出EAR包中执行的第一个文件   sockets Java:如何重用SocketChannel   java通过MQTT和ssl连接安卓设备   java如何修复控制台中的“未知命令”错误?   java为多线程FizzBuzz编写测试用例   java解析findBy中的嵌套对象属性   异常Java:在这种特殊情况下,如何处理ConcurrentModificationException?   从java教科书中绘制图形   java找不到类型为com的响应对象的MessageBodyWriter。太阳运动衫应用程序编程接口。json。JSONWithPadding媒体类型:application/xjavascript   java如何在Android中将光标设置在tableLayout的行/列中所需的位置   Elasticsearch:java。lang.IllegalArgumentException:在docker容器上运行时不允许自我抑制   如何在Java中继承此方法?   java为什么我的消息消费者不接收所有其他消息?   java为什么@ApplicationScoped bean在CDI扩展的关闭前阶段有一个新实例?