在pyspark dataframe中的一列中使用regex捕获两个字符串之间的第一个字符串

roqulrg3  于 2021-05-16  发布在  Spark
关注(0)|答案(1)|浏览(431)

我有一个pyspark dataframe(df),它有一个日期列(数据类型:str)和一个消息列(数据类型str从使用concat\u ws()的列表对象更改而来),如下所示:
示例dataframe

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']

我希望在startstring和stopstring之间提取id:之后的第一个字符串,并丢弃不是第一个出现的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[\s\S]*?ID :\s*(\S*)\b[\s\S]*? Stopstring",1))
result.show()

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

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

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

wribegjk

wribegjk1#

你能做的是:
连接数组(如您所述)
按“stopstring”拆分
分解该列,这意味着您将为数组的每个元素(以及模式的每个引用)获得一行
应用正则表达式。

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[\s\S]*?ID :\s*(\S*)\b[\s\S]*?",1))
  .filter(F.col("parsed_ids") != "")
  .show()

一个问题是,当按“stopmessage”拆分时,这个词将从结果字符串中删除,并且不能在regex模式中使用。

相关问题