使用Polars str.replace时,如何将正则捕获组传递给回调函数?
解决Polars Series中动态展开范围字符串的问题
问题场景
给定如下Polars Series:
import polars as pl s = pl.Series(['{1-5}', '1'])
需要将其中的{1-5}转换为{1, 2, 3, 4, 5},且要通过正则捕获组动态提取范围的起止值,而非手动指定。
可行方案
方法1:使用lambda函数处理正则匹配
Polars的str.replace支持传入lambda函数作为替换值(需指定regex=True),lambda会接收每个匹配的match对象,从中提取捕获组的动态值:
import polars as pl s = pl.Series(['{1-5}', '1']) result = s.str.replace( r'\{(\d+)-(\d+)\}', lambda m: f"{{{', '.join(map(str, range(int(m[1]), int(m[2]) + 1)))}}}", regex=True ) print(result)
输出结果:
shape: (2,) Series: '' [str] [ "{1, 2, 3, 4, 5}" "1" ]
方法2:纯Polars表达式实现(向量化操作)
如果需要在复杂数据流中使用,推荐用纯Polars表达式链,避免逐元素的lambda调用:
import polars as pl s = pl.Series(['{1-5}', '1']) result = ( s.to_frame(name="val") .with_columns( pl.when(pl.col("val").str.contains(r'\{\d+-\d+\}')) .then( pl.format( "{{{}}}", pl.col("val").str.extract(r'(\d+)', 1).cast(pl.Int32) .range(end=pl.col("val").str.extract(r'(\d+)', 2).cast(pl.Int32) + 1) .list.eval(pl.element().cast(pl.Utf8)) .list.join(", ") ) ) .otherwise(pl.col("val")) ) .select("val") .to_series() ) print(result)
输出结果与方法1一致。
原写法问题说明
你之前尝试的f'{set(range(int('${1}'), int('${2}' + 1)))}'无法生效,因为Python的f-string会在执行str.replace前就完成解析,无法获取正则运行时捕获的动态组值。必须通过Polars支持的动态替换逻辑(lambda或表达式链)才能实现需求。
内容的提问来源于stack exchange,提问作者Elis Evans
相关产品推荐
相关产品推荐

