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

如何用正则或pandas内置解析器提取pandas.eval()中的变量

问题描述

我有大量可在脚本中调用并通过pandas.eval()求值的变量,这个方法本质是数学求值器。但执行eval()前需要从多数据源组装DataFrame,因此必须先解析给定表达式,找出所有命名变量,执行搜索方法合并到DataFrame后,再执行eval()。

  • 曾尝试用正则表达式实现,但变量名含空格时会出问题,且我对正则不熟悉。
  • 查看pandas.eval()源码后,尝试复用pandas的解析方法,但发现pandas本身也未解决变量名含空格的问题。
  • 倾向于复用pandas解析器(最稳健方案),但调用pandas.core.computation.expr.Expr类时一直报错:pandas.core.computation.ops.UndefinedVariableError: name 'var1' is not defined,但pandas.eval()执行相同字符串却无此错误,对此感到困惑。

需求

获取eval表达式中所有允许含空格的变量列表,理想输入输出如下:

eval_string = "(var1 / var with spaces 2) + var with spaces 3"
parsed_vars = magic_of_stack_overflow(eval_string)
parsed_vars

输出:

["var1","var with spaces 2","var with spaces 3"]

更理想的是直接复用后续传入表达式的pandas原生解析器。

环境:Python 3.12,pandas 1.3.5


解决方案:复用pandas解析器提取变量(支持含空格的变量名)

通过构造自定义变量访问器和命名空间,绕开未定义变量的错误,同时捕获解析过程中识别到的所有变量名,完全复用pandas原生解析逻辑。

示例代码

import pandas as pd
from pandas.core.computation.expr import Expr
from pandas.core.computation.scope import Scope

class CaptureVariables:
    def __init__(self):
        self.vars = set()
    
    def __getitem__(self, name):
        # 捕获被访问的变量名
        self.vars.add(name)
        # 返回占位值避免解析报错
        return 0

def extract_eval_variables(eval_string):
    capture = CaptureVariables()
    # 注入自定义命名空间,让所有变量访问指向Capture实例
    scope = Scope(globals={}, locals=capture)
    try:
        # 构造Expr实例触发解析
        expr = Expr(eval_string, scope=scope)
        expr.parse()
    except Exception:
        # 忽略求值阶段错误,仅保留已解析的变量
        pass
    # 返回去重后的变量列表
    return list(capture.vars)

# 测试
eval_string = "(var1 / var with spaces 2) + var with spaces 3"
parsed_vars = extract_eval_variables(eval_string)
print(parsed_vars)
# 输出: ['var1', 'var with spaces 2', 'var with spaces 3']

原理说明

  • CaptureVariables类通过__getitem__方法拦截所有变量访问请求,记录变量名并返回占位值,避免解析时因变量未定义报错。
  • 利用pandas的Scope类将自定义变量访问器注入解析环境,确保解析器能正常遍历表达式的抽象语法树(AST)。
  • 完全复用pandas原生解析逻辑,能正确识别带空格的变量名(前提是表达式无语法错误)。

注意事项

  • 若表达式存在语法错误,解析会抛出异常,但仍能捕获已解析到的变量。
  • 该方法适配pandas 1.3.5版本,不同版本的Expr和Scope接口可能略有差异,可查看对应版本源码调整实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 22:21:03