PySpark如何获取字符串列表在列中的位置,但如果不存在则返回零

jjjwad0x  于 12个月前  发布在  Spark
关注(0)|答案(2)|浏览(101)

我最近开始学习PySpark,我试图理解如何返回列中正则表达式模式的位置,但如果列中不存在正则表达式模式,则返回0。
我在StackOverflow上尝试了另一个非常好的答案,它在返回另一个字符串中正则表达式模式开始的位置方面做得很好。https://stackoverflow.com/questions/66121409/locate-function-with-regular-expression-in-spark-sql然而,在这个答案中,当正则表达式模式不存在于字符串中时,它返回1而不是我需要的0。
根据其他答案,我试着调整如下:

spark.sql("select locate(regexp_extract('0000X00', '([X,Y,Z,W])', 1),  '0000X00') as check_pos_string").show()

+----------------+
|check_pos_string|
+----------------+
|               5|
+----------------+

字符串
如预期的那样返回位置5,这是正则表达式模式中的字符X在它正在检查的字符串中出现的位置。
然而,当我尝试以下操作时,它返回1,即使模式不存在于它正在检查的字符串中。

spark.sql("select locate(regexp_extract('0000000', '([X,Y,Z,W])', 1),  '0000000') as check_pos_string").show()

+----------------+
|check_pos_string|
+----------------+
|               1|
+----------------+


如果字符串中不存在正则表达式模式,我想知道如何返回0,而不是1,所以它看起来像下面这样。

+----------------+
|check_pos_string|
+----------------+
|               0|
+----------------+


我有一种感觉,我误解了一些简单的东西,由于我缺乏经验的PySpark!

brgchamk

brgchamk1#

以下是几点:

  • [X,Y,Z,W]是一个character class,它匹配方括号中的所有字符,这意味着它匹配X,Y,Z,W(注意它也匹配逗号)。你实际上想要的是[XYZW]或更简洁的[W-Z]
  • 在表达式中不需要capture group(...);如果没有group,只需将0参数更改为0

因此,对regexp_extract的调用应该如下所示:

regexp_extract('0000X00', '[XYZW]', 0)

字符串
就您的问题而言,这是由于regexp_extract在不匹配任何内容时返回空字符串,而locate在输入的开头“找到”该字符串,因此返回1作为结果。
你可以通过用一个通常不会出现在字符串中的字符 * 替换 * 匹配,然后尝试locate该字符来解决这个问题,例如。

spark.sql("select locate('*', regexp_replace('0000X0Y', '[W-Z]', '*')) as check_pos_string").show()


输出量:
| 检查位置字符串|
| --|
| 5 |
如果没有找到匹配,特殊字符不会被替换到字符串中,因此locate将返回0

spark.sql("select locate('*', regexp_replace('0000000', '[W-Z]', '*')) as check_pos_string").show()


输出量:
| 检查位置字符串|
| --|
| 0 |

flmtquvp

flmtquvp2#

在我看来,没有办法改变regexp_exctract的行为,但有一个变通办法,你可以使用IF语句,当没有匹配时返回0

spark.sql(
  "SELECT CASE WHEN regexp_extract('0000000', '([X,Y,Z,W])', 1) = '' THEN 0 ELSE locate(regexp_extract('0000000', '([X,Y,Z,W])', 1), '0000000') END AS check_pos_string"
).show()

字符串

相关问题