Что такое хороший парсер Python для поискового запроса, подобного Google? - PullRequest
17 голосов
/ 02 марта 2010

Для некоторого кода, основанного на поиске (в Python), мне нужно написать синтаксический анализатор запросов, который бы анализировал простой синтаксис запросов типа Google. Например:

все эти слова "с этой фразой" ИЛИ что ИЛИ этот сайт: внутри. тип файла: ps от: lastweek

Поскольку поиск становится все более популярным, я ожидал, что смогу легко найти библиотеку Python для этого и, таким образом, избежать необходимости заново изобретать колесо. К сожалению, поиск в Google мало что дает.

Что бы вы порекомендовали в качестве библиотеки разбора python для этой простой задачи?

Ответы [ 7 ]

8 голосов
/ 02 марта 2010

Хотя ply является более классическим подходом (Pythonic вариант lexx + yacc) и, следовательно, может быть легче начать, если вы уже знакомы с такими традиционными инструментами, pyparsing очень pythonic и был бы моей главной рекомендацией, особенно для таких простых задач (которые действительно больше похожи на лексические операции, чем на «полноценный» разбор… по крайней мере, до тех пор, пока вы не захотите использовать возможно вложенные скобки, но pyparsing действительно не будет проблематичным тем или иным; -).

3 голосов
/ 30 июня 2014

Несколько хороших вариантов:

  • Черт возьми: единственная проблема в том, что у них мало примеров разбора, так как парсер может не быть его основной функцией / фокусом, но это определенно хороший вариант

  • modgrammar: я не пробовал, но это кажется довольно гибким и простым

  • слойные

  • pyparsing: настоятельно рекомендуется. Есть несколько хороших примеров разбора онлайн

Если вы закончили с проектом, что вы в итоге выбрали?

3 голосов
/ 03 марта 2010

К сожалению - 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, с множеством исправлений и улучшений, появится сравнительно скоро).

2 голосов
/ 24 мая 2016

PyParsing был бы правильным выбором, хотя и довольно утомительным, поэтому я разработал синтаксический анализатор запросов, основанный на синтаксисе lucene и gmail. Это только зависимость PyParsing, и мы использовали его в нескольких проектах. Это полностью настраиваемый и расширяемый, плюс он абстрагирует вас от проблем с pyparsing. Вы можете проверить это здесь:

http://www.github.com/sebastiandev/plyse

Он довольно хорошо документирован, поэтому вы найдете документы о том, как выполнять запросы, конфигурации и т. Д.

2 голосов
/ 02 марта 2010

PLY отлично. Он основан на идиоме Lex / Yacc и, таким образом, может быть уже знаком. Он позволяет создавать произвольно сложные лексеры и парсеры для любой задачи, включая ту, которая вам нужна.

Использование мощного инструмента, такого как PLY, вместо простой игрушки - хорошая идея, потому что ваши потребности со временем могут усложниться, и вы хотите остаться с тем же инструментом.

0 голосов
/ 29 сентября 2015

Я знаю, что это старый вопрос, но для дальнейшего использования я только что загрузил свой пакет searchstringparser в PyPi . Который реализует приличный механизм разбора запросов на основе ply . Он выводит строку, подходящую для функции PostgreSQL tsquery. Вы можете взглянуть на классы lexer и parser, чтобы увидеть, соответствуют ли они вашим потребностям или изменились ли они соответствующим образом.

Обратная связь приветствуется!

0 голосов
/ 20 августа 2013

Whoosh имеет модуль синтаксического анализатора поисковых запросов whoosh.qparser и класс QueryParser, который должен быть достаточно легко адаптирован к вашему варианту использования.

См. http://pythonhosted.org/Whoosh/parsing.html и https://bitbucket.org/mchaput/whoosh/src/55f9c484047a8306101c8eaa59e9a110f960a1c2/src/whoosh/qparser

...