在pySpark SQL函数中使用非消耗式正则表达式

时间:2019-05-16 23:36:49

标签: regex apache-spark pyspark apache-spark-sql

如何使用现有的pySpark sql函数在字符串列中查找非使用的正则表达式模式?

以下内容是可重复的,但没有得到预期的结果。

import pyspark
from pyspark.sql import (
    SparkSession,
    functions as F)

spark = (SparkSession.builder
         .master('yarn')
         .appName("regex")
         .getOrCreate()
         )

sc = spark.sparkContext
sc.version # u'2.2.0'

testdf = spark.createDataFrame([
    (1, "Julie", "CEO"),
    (2, "Janice", "CFO"),
    (3, "Jake", "CTO")],
    ["ID", "Name", "Title"])
ptrn = '(?=Ja)(?=ke)'
testdf.withColumn('contns_ptrn', testdf.Name.rlike(ptrn) ).show()
+---+------+-----+-----------+
| ID|  Name|Title|contns_ptrn|
+---+------+-----+-----------+
|  1| Julie|  CEO|      false|
|  2|Janice|  CFO|      false|
|  3|  Jake|  CTO|      false|
+---+------+-----+-----------+
testdf.withColumn('contns_ptrn', F.regexp_extract(F.col('Name'), ptrn, 1)).show()
+---+------+-----+-----------+
| ID|  Name|Title|contns_ptrn|
+---+------+-----+-----------+
|  1| Julie|  CEO|           |
|  2|Janice|  CFO|           |
|  3|  Jake|  CTO|           |
+---+------+-----+-----------+
testdf.withColumn('contns_ptrn', F.regexp_replace(F.col('Name'), ptrn, '')).show()
+---+------+-----+-----------+
| ID|  Name|Title|contns_ptrn|
+---+------+-----+-----------+
|  1| Julie|  CEO|      Julie|
|  2|Janice|  CFO|     Janice|
|  3|  Jake|  CTO|       Jake|
+---+------+-----+-----------+

所需的结果将是:

+---+------+-----+-----------+
| ID|  Name|Title|contns_ptrn|
+---+------+-----+-----------+
|  1| Julie|  CEO|      false|
|  2|Janice|  CFO|      false|
|  3|  Jake|  CTO|       true|
+---+------+-----+-----------+

“名称”列中的第三行包含“ Ja” “ ke”。

如果regexp_extractregexp_replace能够提取或替换非消耗型正则表达式模式,那么我也可以将它们与length一起使用以获取布尔值列。

1 个答案:

答案 0 :(得分:0)

找到了一个快速的解决方案,希望可以对其他人有所帮助。

idptrn更改为'(?=Ja)(?=ke)''(?=.*Ja)(?=.*ke)'起作用。

这个答案使我接近,但导致了我的问题。 https://stackoverflow.com/a/469951/5060792

这些答案解决了我的问题。 https://stackoverflow.com/a/3041326 https://stackoverflow.com/a/470602/5060792

顺便说一句,rlike除了更改ptrn外,什么都没有抛出regexp_extract异常。将整个模式包装在括号java.lang.IndexOutOfBoundsException: No group 1中后,它返回null。

同样,ptrn = '((?=.*Ja)(?=.*ke))'不替换任何内容,并返回原始值。