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

使用pyparsing解析含括号谓词的嵌套SQL查询求助

问题原因

原有解析逻辑失效的核心原因是infixNotation默认会将所有括号优先识别为逻辑表达式的分组边界,之前定义的字符集匹配规则优先级低于内置的括号分组逻辑,因此解析到第一个闭合括号时就判定第一个逻辑分组结束,直接截断了后续内容,且C In ("a", "b")内部的括号被误判为逻辑分组符,导致整个谓词被拆分。

修复方案

核心思路是先定义合法的原子谓词匹配规则,让解析器优先识别完整谓词(包括谓词内部带引号的字符串、配对的括号块),仅将不属于谓词内部的括号识别为逻辑分组边界,完整可运行代码如下:

from pyparsing import *

# 匹配双引号包裹的字符串,支持转义字符
quoted_str = QuotedString('"', escChar='\\')
# 定义逻辑运算符关键字,提前避免被识别为谓词内容
AND = CaselessKeyword("AND")
OR = CaselessKeyword("OR")
logical_op = AND | OR
# 匹配普通词:非逻辑关键字、不含括号的可打印字符
normal_word = ~logical_op + Word(printables, excludeChars="()")
# 递归匹配谓词内部的配对括号块
pred_paren = Forward()
pred_atom = quoted_str | normal_word | pred_paren
pred_paren <<= "(" + ZeroOrMore(pred_atom) + ")"
# 单个完整谓词:将多个原子单元拼接为完整文本,比如 C In ("a", "b") 会被整体匹配
predicate = originalTextFor(OneOrMore(pred_atom))

# 构建逻辑表达式解析器
expr = infixNotation(
    predicate,
    [
        (logical_op, 2, opAssoc.LEFT)
    ]
)
运行效果

执行测试代码:

query = '(A LIKE "%.something.com" AND B = 4) OR (C In ("a", "b") AND D Contains "asdf")'
print(expr.parseString(query).asList())

会得到预期的输出结构:

[[['A LIKE "%.something.com"', 'AND', 'B = 4'], 'OR', ['C In ("a", "b")', 'AND', 'D Contains "asdf"']]]
规则说明
  • 单独匹配引号字符串,避免引号内出现的AND/OR、括号等字符干扰解析逻辑
  • 通过递归规则匹配配对括号,保证谓词内部(比如IN子句)的括号会被完整包含在原子谓词中,不会被误判为逻辑分组符
  • 只有顶层用来划分逻辑优先级的括号,才会被infixNotation识别为分组边界,符合SQL条件表达式的语法规则

内容的提问来源于stack exchange,提问作者Guy Jacoby

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 07:18:15