Для некоторого основанного на поиске кода (в Python), я должен записать синтаксический анализатор синтаксиса запроса, который проанализировал бы простой Google как синтаксис запроса. Например:
все эти слова "с этой фразой" ИЛИ этим ИЛИ этим site:within.site filetype:ps from:lastweek
Поскольку поиск становится больше более популярным, я ожидал быть в состоянии легко найти библиотеку Python для того, чтобы сделать это и таким образом избежать необходимости изобретать велосипед. К сожалению, поиски на Google не уступают очень.
Что Вы рекомендовали бы как библиотека парсинга Python для этой простой задачи?
Хотя ply
является более классическим подходом (питоновский вариант lexx + yacc) и, следовательно, может быть проще начать, если вы уже знакомы с такими традиционными инструментами, pyparsing сильно питоничен и был бы моей главной рекомендацией, особенно для таких простых задач (которые на самом деле больше похожи на лексирование, чем на «полномасштабный» синтаксический анализ ... по крайней мере, до тех пор, пока вы не захотите разрешить возможно вложенные круглые скобки, но они тоже не будут беспокоить pyparsing ;-).
ИЗВИНИТЕ - Лепл больше не разрабатывается .
Также есть 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 с множеством исправлений и улучшений).
PLY - отличный вариант. Он основан на идиоме Lex/Yacc и поэтому может быть вам уже знаком. Он позволяет создавать произвольно сложные лексеры и синтаксические анализаторы для любой задачи, включая ту, которая вам нужна.
Использование такого мощного инструмента, как PLY, вместо простой игрушки - хорошая идея, потому что ваши потребности могут усложниться со временем, а вы хотели бы остаться с одним и тем же инструментом.