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

PySpark中如何原生提取正则表达式的多匹配结果?

实现PySpark原生正则多匹配分组的数组提取

首先得明确:PySpark确实没有提供直接返回所有正则匹配分组列表的原生函数(比如类似Python re.findall的功能),但我们可以通过组合几个原生函数来实现这个需求,完全不需要写基于re.findall的UDF。

针对你的场景(正则只有一个分组,需要获取所有匹配的分组值组成数组),可以按以下步骤操作:

步骤1:收集所有匹配的分组值并转成数组

我们可以利用regexp_replace把每个匹配的分组值用一个特殊分隔符拼接起来,再用split转成数组,最后过滤掉可能的空元素:

from pyspark.sql import SparkSession
from pyspark.sql import functions as F

# 初始化SparkSession
spark = SparkSession.builder.appName("RegexMatches").getOrCreate()

# 测试数据
df = spark.createDataFrame([("2 AVENUE DES LAPINOUS",)], ["col_name"])

# 定义正则(你的场景是单分组:(\w+))
my_regex = r"(\w+)"
# 用不可见分隔符\u0001避免和原字符串内容冲突
separator = r"\u0001"

# 1. 用regexp_replace把所有匹配的分组值用分隔符拼接
# 2. split转成数组
# 3. filter过滤掉最后可能的空元素(因为最后一个匹配后也会加分隔符)
df = df.withColumn(
    "matches_array",
    F.expr(f"filter(split(regexp_replace(col_name, '{my_regex}', r'$1{separator}'), '{separator}'), x -> x != '')")
)

执行后,matches_array列的值就是["2", "AVENUE", "DES", "LAPINOUS"],完全符合你要的所有匹配分组的列表。

步骤2:操作数组中的元素

得到数组后,你就可以像操作普通PySpark数组一样访问元素了,比如实现你示例里的$1[0] - $1[1]逻辑(注意你示例里的$2应该是笔误,因为你的正则只有一个分组):

df = df.withColumn(
    "result",
    F.concat(
        F.col("matches_array")[0],
        F.lit(" - "),
        F.col("matches_array")[1]
    )
)

# 查看结果
df.select("col_name", "matches_array", "result").show(truncate=False)

输出结果:

+------------------------+------------------------------+-------------+
|col_name                |matches_array                 |result       |
+------------------------+------------------------------+-------------+
|2 AVENUE DES LAPINOUS   |[2, AVENUE, DES, LAPINOUS]    |2 - AVENUE   |
+------------------------+------------------------------+-------------+

扩展:多分组的情况(可选)

如果你的正则有多个分组,比如(\d+) (\w+),想要收集每个匹配的多分组值,可以用不同的分隔符区分分组和匹配,比如用;分隔每个匹配项,用|分隔分组:

multi_regex = r"(\d+) (\w+)"
df_multi = spark.createDataFrame([("2 AVENUE 3 STREET",)], ["col_name"])

df_multi = df_multi.withColumn(
    "matches_struct",
    F.expr("""
        transform(
            filter(split(regexp_replace(col_name, '{multi_regex}', r'$1|$2;'), ';'), x -> x != ''),
            x -> struct(split(x, '|')[0] as num, split(x, '|')[1] as word)
        )
    """)
)

这样就能得到一个结构体数组,每个元素包含匹配的两个分组值。

关键说明

  • 选择分隔符时,尽量用原字符串中不会出现的字符(比如\u0001这种不可见控制字符),避免拆分时出错。
  • 整个流程完全使用PySpark原生函数,不需要依赖Python的re库,性能比UDF更优,尤其是大数据量场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:43:38