在pyspark数据帧的列中使用regex捕获两个字符串之间第一个出现的字符串



我有一个pyspark数据帧(df(,它有一个日期列(数据类型:str(和一个消息列(使用concat_ws((从列表对象更改的数据类型str(,如下所示:

示例数据帧

Date               message
2020-11-01         ['some not required text1', 'Startstring ID :AB_CD', 
'some not required text2', 'ID :EDGH', 'some not 
required text3', 'ID :XYZ', 'Stopstring' 'some not 
required text4', 'Startstring ID :cd_ab', 'some not 
required text5', 'ID :ghed', 
'some not required text6', ID :zyx', 'Stopstring 'some 
not required text7']
2020-11-02         ['some not required text8', Startstring 'ID :ABCD', 
'some not required text9', 'ID :ED_GH', 'some not 
required text10', ID :X_YZ, Stopstring 'some not 
required text11', 'Startstring 
ID :cdab', 'some not required text12', 'ID :gh_ed', 
'some not required text13', ID :z_yx', 'Stopstring 
'some not required text14']

我希望提取字符串的第一个出现在ID之后,在Startstring和Stopstring之间,并丢弃不是第一个出现的ID。在一个日期内可能存在多个此类实例。

预期输出:

Date               message
2020-11-01         AB_CD 
2020-11-01         cd_ab
2020-11-02         ABCD 
2020-11-02         cdab

我尝试提取ID后第一个出现的字符串:as:

import pyspark.sql.functions as F
from pyspark.sql.types import *
result = df.withColumn("message", F.regexp_extract(col("message"), r"Startstring[sS]*?ID :s*(S*)b[sS]*? Stopstring",1))
result.show()

它只在特定日期第一次给我ID后面的字符串,如下所示:

Date               message
2020-11-01         AB_CD 
2020-11-02         ABCD

非常感谢在这方面提供的帮助。感谢

您可以做的是:

  • 连接数组(如您所述(
  • 除以";停止串">
  • 分解列,这意味着为数组的每个元素(因此为模式的每次出现(获得一行
  • 应用正则表达式
df
.withColumn("concat_message", F.concat_ws(" ",F.col("message")))
.withColumn("split_message", F.split(F.col("concat_message"), "Stopstring"))
.withColumn("exploded_message", F.explode(F.col("split_message")))
.withColumn("parsed_ids", F.regexp_extract(F.col("exploded_message"), r"Startstring[sS]*?ID :s*(S*)b[sS]*?",1))
.filter(F.col("parsed_ids") != "")
.show()

一个问题是,当用";停止消息";该单词将从生成的字符串中删除,并且不能在Regex模式中使用。

最新更新