PySpark中是否有类似于python的re.findall()函数的功能?

时间:2019-11-21 16:30:29

标签: regex apache-spark pyspark

对于一项作业,我需要在注释中提取所有“提及”。在普通的python中,我会这样做:

string = "@rjberger10 @geneh19 home"
re.findall(r'@\w+', string)

这将给我这样的数组:['@ rjberger10','@ geneh19']。但是赋值指出我们必须使用PySpark方式,但是我在PySpark中找不到类似于findall()的函数。我最接近的是:

result = dict_comments[13].withColumn("@tjes", regexp_extract(col("Text"), r'(@\w+)', 0))

但这只是第一次给我使用@,因此,当有多个提及时,我只会找到一个。

2 个答案:

答案 0 :(得分:1)

另一种方法可能是先删除字符串中与模式不匹配的部分,然后在空白处分割其余文本:

from pyspark.sql.functions import col, split, regexp_replace

df.withColumn(
    "@tjes", 
    split(regexp_replace(col("Text"), r'(\s|^)[^@]\w+(\s|$)', ''), '\s+')
).show(truncate=False)
#+-------------------------+-----------------------+
#|Text                     |@tjes                  |
#+-------------------------+-----------------------+
#|@rjberger10 @geneh19 home|[@rjberger10, @geneh19]|
#+-------------------------+-----------------------+

regexp_replace中使用的模式是:

  • (\s|^):空格或字符串开头
  • [^@]:不是@字符
  • \w+:任意数量的文字字符
  • (\s|$):空格或字符串结尾

答案 1 :(得分:0)

我有一种使用explodesplitregexp_extractcollect_list的方法。

re_df = spark._sc.parallelize([[1,"@rjberger10"], 
                               [2,"@geneh19"],
                               [3,"home"],
                               [4,"@geneh19 @rjberger10"]]).toDF(["id","test_string"])


temp_column_name = "explode_on_split"

(
    re_df.withColumn(temp_column_name, 
                     f.explode(f.split(f.col("test_string"), " "))) 
         .withColumn('extract', 
                     f.regexp_extract(f.col(temp_column_name), r'(@\w+)', 1))
         .groupBy(f.col('test_string'))
         .agg(
           f.collect_list(f.col('extract')).alias('final_extract'))
).show()

+--------------------+--------------------+
|         test_string|       final_extract|
+--------------------+--------------------+
|@geneh19 @rjberger10|[@geneh19, @rjber...|
|         @rjberger10|       [@rjberger10]|
|                home|                  []|
|            @geneh19|          [@geneh19]|
+--------------------+--------------------+

我知道这看起来很麻烦,所以请解释一下: 我在空间上划分,将输出分解为行,用正则表达式扩展输出并按此顺序收集。 但是,如果您查看Spark GitHub页面,您可以期望此功能会在已经有开放的PR(https://github.com/apache/spark/pull/21985)时立即弹出。 希望这会有所帮助!