我用 pyparsing 做了一个语法,但我遇到了问题。 语法尝试解析搜索查询(使用运算符优先级、括号等),我需要空格才能像 and 运算符一样工作。
例如,这工作正常:
(word and word) or word
但这失败了:
(word word) or word
我希望第二个查询像第一个查询一样工作。
我的实际语法是:
WWORD = printables.replace("(", "").replace(")", "")
QUOTED = quotedString.setParseAction(removeQuotes)
OAND = CaselessLiteral("and")
OOR = CaselessLiteral("or")
ONOT = "-"
TERM = (QUOTED | WWORD)
EXPRESSION = operatorPrecedence(TERM,
[
(ONOT, 1, opAssoc.RIGHT),
(OAND, 2, opAssoc.LEFT),
(OOR, 2, opAssoc.LEFT)
])
STRING = OneOrMore(EXPRESSION) + StringEnd()
最佳答案
解决您的问题的一种方法是将 AND 定义为可选运算符。如果这样做,您必须格外小心,以免将“and”和“or”等真实关键字误解为搜索词。此外,借助 Optional,您可以添加一个默认字符串,这样即使原始搜索查询中缺少“and”,您解析的文本也会为您插入它(以便于解析后处理)。
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']]
关于python - 运营商的 Pyparsing 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5059482/