我正在尝试解析一系列数学公式,并且需要使用 Python 中的 Polars 有效地提取变量名称。 Polars 中的正则表达式支持似乎很有限,特别是对于环视断言。 有没有一种简单、有效的方法来解析公式中的符号?
这是我的代码片段:
import re
import polars as pl
# Define the regex pattern
FORMULA_DECODER = r"\b[A-Za-z][A-Za-z_0-9_]*\b(?!\()"
# \b # Assert a word boundary to ensure matching at the beginning of a word
# [A-Za-z] # Match an uppercase or lowercase letter at the start
# [A-Za-z0-9_]* # Match following zero or more occurrences of valid characters (letters, digits, or underscores)
# \b # Assert a word boundary to ensure matching at the end of a word
# (?!\() # Negative lookahead to ensure the match is not followed by an open parenthesis (indicating a function)
# Sample formulas
formulas = ["3*sin(x1+x2)+A_0",
"ab*exp(2*x)"]
# expected result
pl.Series(formulas).map_elements(lambda formula: re.findall(FORMULA_DECODER, formula), return_dtype=pl.List(pl.String))
# Series: '' [list[str]]
# [
# ["x1", "x2", "A_0"]
# ["ab", "x"]
# ]
# Polars does not support this regex pattern
pl.Series(formulas).str.extract_all(FORMULA_DECODER)
# ComputeError: regex error: regex parse error:
# \b[A-Za-z][A-Za-z_0-9_]*\b(?!\()
# ^^^
# error: look-around, including look-ahead and look-behind, is not supported
由于Polars不支持环视断言,我们可以通过应用两次正则表达式来解决这个问题:
import polars as pl
# Define the regex patterns
FORMULA_DECODER = r"\b[A-Za-z][A-Za-z_0-9_]*\b" # Extract all potential variables
FUNCTION_CALL = r"[A-Za-z_][A-Za-z0-9_]*\(" # Detect function calls
# Sample formulas
formulas = ["3*sin(x1+x2)+A_0",
"ab*exp(2*x)"]
df = pl.DataFrame({"formula": formulas})
df = (
df
.with_column(
pl.col("formula")
.str.extract_all(FORMULA_DECODER)
.alias("potential_variables")
)
.with_column(
pl.col("formula")
.str.extract_all(FUNCTION_CALL)
.alias("functions")
)
)
def filter_variables(row):
potential_variables = row["potential_variables"]
functions = row["functions"]
if potential_variables is None or functions is None:
return None
variables = [var for var in potential_variables if var not in functions]
return variables
df = df.with_column(
pl.struct(["potential_variables", "functions"])
.apply(lambda row: filter_variables(row))
.alias("variables")
).select("formula", "variables")
print(df)
这段代码执行以下操作:
- 定义两个正则表达式:
-
FORMULA_DECODER
:这与之前的模式相同,但没有环视断言。它提取所有看起来像变量的东西。 -
FUNCTION_CALL
:这个模式检测函数调用,捕获函数名称及其开括号。 -
使用
extract_all
提取潜在变量和函数调用。 -
创建一个新列
variables
: -
使用
with_column
和apply
迭代每一行。 -
对于每一行,它都会检查
potential_variables
列表中是否存在任何元素,这些元素也包含在functions
列表中。如果是这样,则表示该变量实际上是一个函数调用,并且从结果中将其删除。 -
最后,它打印出包含公式及其提取变量的数据框。
这种方法通过首先提取所有潜在变量,然后过滤掉函数调用来避免使用环视断言。这是一种在Polars中实现所需结果的更有效且更易读的方法。
标签:python,regex,python-polars,text-extraction From: 78785661