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
相关产品推荐
相关产品推荐

