python - 运营商的 Pyparsing 问题

标签 python pyparsing

我用 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/

相关文章:

python - 使用 pyparsing 匹配行开头的空格

python - 无需重新从python中的字符串中提取数字

python - 当匹配失败时 StringEnd() 引发异常 - PyParsing

python - 如何使用 pyparsing 验证 bool 表达式语法?

python - 将 Netscaler 显示输出转换为 BNF 进行解析

python - 评估 WFF 逻辑表达式时出现 Pyparsing 错误?

python - groupby 一列并将剩余列转换为字典

python - 如何在 Python 中读取间隔中的行?

python - 有没有办法让 python 解释控制台一次导入我的整个应用程序?

python - 如何绘制图形聚类系数的分布