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

Pyparsing:如何收集表达式中所有嵌套的变量名?

使用pyparsing正确提取表达式中所有嵌套变量名(排除关键字)

要解决嵌套结构下变量分散、关键字误识别的问题,别死磕setResultsName的嵌套结果,直接用**解析动作(parseAction)**在匹配变量时实时收集,同时提前排除关键字即可。

步骤1:定义基础规则(关键字+变量)

先明确你的表达式里哪些是关键字(比如if/else这类),然后定义变量规则——只匹配标识符,但排除关键字:

import pyparsing as pp

# 替换成你表达式里的实际关键字
KEYWORDS = {"if", "else", "while", "for", "and", "or", "not"}
keyword_parser = pp.MatchFirst(pp.Keyword(k) for k in KEYWORDS)

# 定义变量:字母开头,可包含字母/数字/下划线,且不是关键字
variable = pp.Word(pp.alphas, pp.alphanums + "_").setName("variable")
variable = ~keyword_parser + variable  # ~表示"非",排除关键字匹配

步骤2:用解析动作收集变量

不用依赖嵌套的结果结构,给变量规则加一个解析动作,每次匹配到变量就塞进集合里(自动去重):

# 用类管理收集的变量,避免全局变量
class VarCollector:
    def __init__(self):
        self.collected = set()
    
    def add_var(self, tokens):
        self.collected.add(tokens[0])

# 绑定收集动作
collector = VarCollector()
variable.setParseAction(collector.add_var)

步骤3:定义表达式语法并解析

按你的表达式语法定义完整的解析规则(比如带括号的加减乘除),然后直接解析即可:

# 定义带括号、支持加减乘除的表达式
expr = pp.infixNotation(
    variable | pp.pyparsing_common.number,  # 原子:变量或数字
    [
        (pp.oneOf("* /"), 2, pp.opAssoc.LEFT),  # 乘除优先级更高
        (pp.oneOf("+ -"), 2, pp.opAssoc.LEFT),
    ]
)

# 测试解析嵌套表达式
collector.collected.clear()
expr.parseString("(a + b) * (c - if)")
print(collector.collected)  # 输出 {'a', 'b', 'c'} —— if是关键字,被排除

为什么这个方法靠谱?

  • 不管变量在多少层括号/分组里,只要匹配到就会触发解析动作,直接收集,完全避开嵌套结果的麻烦;
  • 通过~keyword_parser直接排除关键字匹配,从根源避免误识别;
  • 集合自动去重,不用担心重复变量被多次收集。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:35:16