You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pyparsing使用infixNotation时如何将条件间空白识别为隐式AND运算符

你当前代码的核心问题在于pyparsing默认会自动跳过输入中的所有空白字符,所以你将空格加入AND的可选值是无效的,空白不会被当作有效token进入解析流程,解析器识别完第一个括号表达式后没有找到显式运算符,就会直接停止解析,忽略后续内容。

解决方法

  1. 拆分显式AND和隐式AND的定义,隐式AND使用Empty()实现,不需要匹配任何实际字符,仅匹配两个表达式相邻的位置
  2. 调整运算符优先级:按NOT > 隐式AND > 显式AND > OR的顺序配置,符合搜索语法的常规逻辑
  3. 隐式AND的解析结果和显式AND对齐,方便后续统一处理

修改后的完整代码如下:

import pyparsing as pp
from pyparsing import Word, alphanums, Empty, oneOf 

field_name = Word(alphanums).setResultsName('field_name')
search_value = Word(alphanums + '-').setResultsName('search_value')
operator = pp.Literal(':')
query = field_name + operator + search_value

# 拆分显式AND和隐式AND
EXPLICIT_AND = oneOf(['AND', 'and', '&'])
# 隐式AND不匹配任何实际字符,解析后统一返回&,和显式AND对齐
IMPLICIT_AND = Empty().setParseAction(lambda: "&")
OR = oneOf(['OR', 'or', '|'])
NOT = oneOf(['NOT', 'not', '!'])

query_expr = pp.infixNotation(query, [
    (NOT, 1, pp.opAssoc.RIGHT, ),
    (IMPLICIT_AND, 2, pp.opAssoc.LEFT, ), # 隐式AND优先级高于显式AND
    (EXPLICIT_AND, 2, pp.opAssoc.LEFT, ),
    (OR, 2, pp.opAssoc.LEFT, ),
])

class ComparisonExpr:
    def __init__(self, tokens):
        self.tokens = tokens
    def __str__(self):
        return "Comparison:('field': {!r}, 'operator': {!r}, 'value': {!r})".format(*self.tokens)
    def __repr__(self):
        return self.__str__()

query.addParseAction(ComparisonExpr)

# 测试无显式运算符的样本
sample = "(field1:value1a | field1:value1b) (field2:value2a | field2:value2b)"
result = query_expr.parseString(sample).asList()

from pprint import pprint
pprint(result)

运行输出结果符合预期:

[[[Comparison:('field': 'field1', 'operator': ':', 'value': 'value1a'),
   '|',
   Comparison:('field': 'field1', 'operator': ':', 'value': 'value1b')],
  '&',
  [Comparison:('field': 'field2', 'operator': ':', 'value': 'value2a'),
   '|',
   Comparison:('field': 'field2', 'operator': ':', 'value': 'value2b')]]]

如果需要隐式AND和显式AND优先级相同,可以将两者合并到同一个优先级组:

query_expr = pp.infixNotation(query, [
    (NOT, 1, pp.opAssoc.RIGHT, ),
    ((EXPLICIT_AND | IMPLICIT_AND), 2, pp.opAssoc.LEFT, ),
    (OR, 2, pp.opAssoc.LEFT, ),
])

内容的提问来源于stack exchange,提问作者Nathan Jones

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 00:54:05