有哪些适合像Google一样的搜索查询的Python解析器?

18

对于一些基于搜索的Python代码,我需要编写一个查询语法解析器,用于解析类似 Google 的简单查询语法。例如:

所有这些词 "带有这个短语" OR 那个 OR 这个 site:within.site filetype:ps from:lastweek

随着搜索变得越来越流行,我希望能够轻松地找到一个Python库来完成这项任务,从而避免重新发明轮子。不幸的是,在谷歌上的搜索并没有得到很多结果。

您会推荐哪个 Python 解析库来完成这个简单的任务呢?


您可能想要查看Apache Lucene。据我了解,它做的事情非常相似,尽管它是用Java编写的,而不是Python(尽管您可以使用Jython与其进行接口)。 - Michael Aaron Safyan
7个回答

8

虽然ply是一种更经典的方法(Pythonic变体的lexx + yacc),因此如果您已经熟悉这些传统工具,那么可能更容易入门,但pyparsing非常符合Python风格,特别适合这样简单的任务(实际上更像词法分析而不是“完整”的解析...至少在您想要允许可能嵌套括号之前,但pyparsing也不会受到这些问题的困扰;-)。


3
谢谢宣传,Alex!pyparsing示例页面包括一个简单的搜索查询解析器(http://pyparsing.wikispaces.com/file/view/searchparser.py),而Whoosh搜索库(http://whoosh.ca/)使用pyparsing进行查询解析。 - PaulMcG
链接已经失效。这是一个存档版本:https://web.archive.org/web/20180105222946/http://pyparsing.wikispaces.com/file/view/searchparser.py - Matt Hancock

4
几个不错的选择:
  • Whoosh:唯一的问题是他们很少提供解析示例,因为解析器可能不是其主要功能/焦点,但它绝对是一个不错的选择

  • modgrammar:我没有尝试过,但它似乎非常灵活和简单

  • ply

  • pyparsing:强烈推荐。有一些好的在线解析示例

如果你完成了项目,你最终选择了什么?


3

抱歉 - Lepl不再被开发。

这里还有一个LEPL - http://www.acooke.org/lepl

以下是我在早餐时写的快速解决方案:

pl6 src: python3                                                      
Python 3.1 (r31:73572, Oct 24 2009, 05:39:09)                         
[GCC 4.4.1 [gcc-4_4-branch revision 150839]] on linux2                
Type "help", "copyright", "credits" or "license" for more information.
>>> from lepl import *                                                
>>>                                                                   
>>> class Alternatives(Node):                                         
...     pass                                                          
...
>>> class Query(Node):
...     pass
...
>>> class Text(Node):
...     pass
...
>>> def compile():
...     qualifier      = Word() & Drop(':')           > 'qualifier'
...     word           = ~Lookahead('OR') & Word()
...     phrase         = String()
...     text           = phrase | word
...     word_or_phrase = (Optional(qualifier) & text) > Text
...     space          = Drop(Space()[1:])
...     query          = word_or_phrase[1:, space]    > Query
...     separator      = Drop(space & 'OR' & space)
...     alternatives   = query[:, separator]          > Alternatives
...     return alternatives.string_parser()
...
>>> parser = compile()
>>>
>>> alternatives = parser('all of these words "with this phrase" '
...                       'OR that OR this site:within.site '
...                       'filetype:ps from:lastweek')[0]
>>>
>>> print(str(alternatives))
Alternatives
 +- Query
 |   +- Text
 |   |   `- 'all'
 |   +- Text
 |   |   `- 'of'
 |   +- Text
 |   |   `- 'these'
 |   +- Text
 |   |   `- 'words'
 |   `- Text
 |       `- 'with this phrase'
 +- Query
 |   `- Text
 |       `- 'that'
 `- Query
     +- Text
     |   `- 'this'
     +- Text
     |   +- qualifier 'site'
     |   `- 'within.site'
     +- Text
     |   +- qualifier 'filetype'
     |   `- 'ps'
     `- Text
         +- qualifier 'from'
         `- 'lastweek'
>>>

我认为LEPL不是“玩具” - 虽然它是递归下降的,但它包括记忆化和尾递归,这有助于避免该方法的一些限制。

然而,它是纯Python编写的,因此速度不是特别快,并且正在积极开发中(一个新版本4.0很快就会发布,其中包含了相当多的修复和改进)。


3
我推荐使用PyParsing,尽管它相当繁琐,这就是我基于lucene和gmail语法开发查询解析器的原因。它只依赖于PyParsing,并且我们在多个项目中使用了它。它完全可定制和可扩展,此外,它还可以帮助你抽象出pyparsing问题。你可以在这里查看:http://www.github.com/sebastiandev/plyse
它有非常好的文档,所以你可以在文档中找到如何进行查询、配置等信息。

2
PLY很棒。它基于Lex/Yacc语法习惯,因此可能已经很熟悉了。它允许您为任何任务创建任意复杂的词法分析器和解析器,包括您需要的那个。
使用像PLY这样强大的工具而不是简单的玩具是一个好主意,因为您的需求随着时间的推移可能会变得更加复杂,而您希望使用同样的工具。

1
我知道这是一个老问题,但为了以后的参考,我刚刚上传了我的软件包searchstringparserPyPi。它基于ply实现了一个体面的查询解析机制。它输出适用于PostgreSQL函数tsquery的字符串。您可以查看词法分析器和解析器类,以确定它们是否符合您的需求,或进行相应修改。
欢迎反馈!

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接