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

Spark SQL 2.4.0中regexp_extract_all函数的替代实现方案

在Spark SQL 2.4.0中实现批量提取电话号码(替代regexp_extract_all)

因为Spark SQL 2.4.0没有内置的regexp_extract_all函数,你可以通过以下两种方式实现批量提取所有匹配的电话号码:

方法一:纯Spark SQL实现(无需代码开发)

利用regexp_replace、split和filter组合实现,核心思路是把非匹配内容统一替换成分隔符,再拆分过滤空值:

SELECT
  original_column,
  filter(
    split(
      regexp_replace(
        original_column,
        -- 注意:根据你的号码格式调整正则,示例适配提供的+1/1/8开头的号码
        '((8|\\+1|1)[\\- ]?)?(\\(?\\d{3}\\)?[\\- ]?)?([\\d]{3}[\\- ]?[\\d]{2}[\\- ]?[\\d]{2})',
        ',$0,' -- 给每个匹配到的号码前后加逗号,统一分隔符
      ),
      ','
    ),
    x -> x != '' -- 过滤拆分后产生的空字符串
  ) AS phone_numbers
FROM your_table_name

说明

  1. regexp_replace会把每个匹配的电话号码用逗号包裹,将原字符串中所有非号码内容(比如原有的逗号、空格)转化为连续逗号;
  2. split(',')将字符串拆分为数组,此时数组中会包含空元素;
  3. filter去掉空元素,最终得到纯电话号码的数组。

方法二:自定义UDF(更灵活可靠)

如果正则替换的方式遇到复杂边缘场景处理不佳,可以编写Scala UDF实现精准匹配:

步骤1:编写并注册UDF

import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions.udf
import java.util.regex.Pattern

val spark = SparkSession.builder().getOrCreate()

// 定义提取电话号码的UDF
val extractAllPhones = udf((input: String) => {
  // 匹配电话号码的正则(根据实际格式调整)
  val phoneRegex = Pattern.compile("((8|\\+1|1)[\\- ]?)?(\\(?\\d{3}\\)?[\\- ]?)?([\\d]{3}[\\- ]?[\\d]{2}[\\- ]?[\\d]{2})")
  val matcher = phoneRegex.matcher(input)
  val result = scala.collection.mutable.ListBuffer[String]()
  // 遍历所有匹配结果
  while (matcher.find()) {
    result += matcher.group()
  }
  result.toArray
})

// 注册到Spark SQL中
spark.udf.register("extract_all_phones", extractAllPhones)

步骤2:在SQL中使用

SELECT
  original_column,
  extract_all_phones(original_column) AS phone_numbers
FROM your_table_name

关键提示

  • 正则适配:你提供的原正则针对的是+7/8/7开头的号码,但示例数据是+1/1开头,需要根据实际业务的号码格式调整正则中的前缀部分(把(8|\+7|7)替换为(8|\+1|1)),否则会匹配不到示例中的号码;
  • 性能考虑:纯SQL方式适合简单场景,UDF方式在复杂匹配逻辑下更稳定,但需要注意UDF的序列化性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 00:09:32