如何用PySpark的regexp_extract提取DataFrame重复标签的多列数据
PySpark提取重复标签的多匹配项解决方案
方法一:两次调用regexp_extract分别提取
针对固定数量的重复标签(这里是2个:17A:),可以通过两次调用regexp_extract,分别捕获第一个和第二个匹配的内容:
import pyspark.sql.functions as F # 提取第一个:17A:后的内容,生成17A_1列 df = df.withColumn('17A_1', F.trim(F.regexp_extract(F.col('data'), ':17A:(.*?):', 1))) # 提取第二个:17A:后的内容,生成17A_2列 df = df.withColumn('17A_2', F.trim(F.regexp_extract(F.col('data'), '.*:17A:.*?:17A:(.*?):', 1)))
正则说明
- 提取17A_1的正则
':17A:(.*?):':匹配:17A:后到下一个:之间的非贪婪内容,捕获组1对应第一个目标值。 - 提取17A_2的正则
'.*:17A:.*?:17A:(.*?):':用.*:17A:.*?跳过第一个:17A:及其内容,再捕获第二个:17A:后的目标值。
方法二:提取所有匹配项为数组后拆分
如果不确定匹配项数量,可先将所有:17A:后的内容提取为数组,再按索引拆分列:
import pyspark.sql.functions as F # 提取所有:17A:相关片段,拆分后得到数组 df = df.withColumn('17A_array', F.split(F.regexp_replace(F.col('data'), '.*?(?:(:17A:(.*?):))+.*', '$0'), ':17A:')) # 从数组中取第2、3个元素(数组第一个元素是前缀垃圾数据) df = df.withColumn('17A_1', F.trim(F.element_at(F.col('17A_array'), 2))) \ .withColumn('17A_2', F.trim(F.element_at(F.col('17A_array'), 3))) \ .drop('17A_array')
效果验证
处理示例数据后,输出结果将符合预期:
| 17A_1 | 17A_2 |
|---|---|
| ACCT//1011112 | BNK//123 |
| MMT//11234 | ACK//9999999 |
内容的提问来源于stack exchange,提问作者kmr
相关产品推荐
相关产品推荐

