Один из способов решения вашей проблемы - определить AND как необязательный оператор. Если вы сделаете это, вам нужно будет позаботиться о том, чтобы реальные ключевые слова, такие как «и» и «или», не интерпретировались как поисковые слова. Кроме того, с помощью Optional вы можете добавить строку по умолчанию, так что даже если в исходном поисковом запросе отсутствует «и», ваш проанализированный текст вставит его для вас (для упрощения обработки после разбора).
from pyparsing import *
QUOTED = quotedString.setParseAction(removeQuotes)
OAND = CaselessLiteral("and")
OOR = CaselessLiteral("or")
ONOT = Literal("-")
WWORD = ~OAND + ~OOR + ~ONOT + Word(printables.replace("(", "").replace(")", ""))
TERM = (QUOTED | WWORD)
EXPRESSION = operatorPrecedence(TERM,
[
(ONOT, 1, opAssoc.RIGHT),
(Optional(OAND,default="and"), 2, opAssoc.LEFT),
(OOR, 2, opAssoc.LEFT)
])
STRING = OneOrMore(EXPRESSION) + StringEnd()
tests = """\
word and ward or wird
word werd or wurd""".splitlines()
for t in tests:
print STRING.parseString(t)
Дает:
[[['word', 'and', 'ward'], 'or', 'wird']]
[[['word', 'and', 'werd'], 'or', 'wurd']]