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

如何用Regex和Polars高效解析数学公式中的变量名?

解决Polars中无法用环视正则提取数学公式变量名的问题

由于Polars的字符串正则基于RE2引擎,不支持环视断言(比如(?!\()),可以换一种思路:先提取所有符合变量/函数命名规则的标识符,再过滤掉后面紧跟(的函数名,既能利用Polars原生矢量化操作的高效性,又能得到目标变量名。

实现代码

import polars as pl

# 正则匹配所有符合命名规则的标识符(包括带(的函数名)
FORMULA_PATTERN = r"\b[A-Za-z][A-Za-z0-9_]*\b\(?"

# 示例公式
formulas = ["3*sin(x1+x2)+A_0", "ab*exp(2*x)"]

# 提取并过滤得到变量名
result = (
    pl.Series(formulas)
    .str.extract_all(FORMULA_PATTERN)
    # 过滤掉包含(的元素(即函数名)
    .list.eval(pl.element().filter(~pl.element().str.contains("(", literal=True)))
)

print(result)
# 输出:
# Series: '' [list[str]]
# [
#   ["x1", "x2", "A_0"]
#   ["ab", "x"]
# ]

思路说明

  1. 正则调整:把原方案中的负向环视(?!\()替换成可选匹配\(?,这样会捕获两类内容:
    • 普通变量名(如x1、A_0)
    • 带括号前缀的函数名(如sin(、exp()
  2. 过滤处理:借助Polars的list.eval和filter方法,移除包含(的元素,剩下的就是纯变量名。

性能对比(基于提供的基准测试)

测试结果显示三种方案的性能差异:

  • parse_lookahead(map_elements调用Python原生re):10.7 ms/循环
  • parse_no_lookahead_and_filter(Polars原生操作):1.31 ms/循环
  • parse_baseline(未过滤函数名):708 μs/循环

可见,这种方案既准确排除了函数名,性能又接近基准水平,比用map_elements快一个数量级,完全发挥了Polars矢量化计算的优势。

注意事项

  • 绝大多数数学公式中,(前的标识符都是函数名,该逻辑能覆盖常规场景;若存在变量名后紧跟(的极端情况,需根据实际需求微调规则。
  • 使用literal=True处理(,是为了避免将其当作正则元字符,确保匹配准确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:58:18