如何在 Spark 中执行正则表达式 SQL
How to do regEx in Spark SQL
我必须创建一个数据框,其中一列中的行应该是我从长 URL 中提取的名称。假设我有以下 url:
https://xxx.xxxxxx.com/xxxxx/y...y/?...?/<irrelevant>
现在不幸的是我不能透露确切的 URLs 但我可以说的是字母 x
包含不变的字符串(即所有 URLs在数据库中包含这些模式并且是已知的),y...y
是一个未知的用户名,长度未知并且可能随每个 URL 而改变 ?...?
是我的名字我对(又是一个长度未知的字符串)感兴趣。之后可能会有多个字符串被 /
分隔,这些字符串没有用。我该怎么做呢?到目前为止,我曾经做过三种不同的 UDF,它们使用子字符串和索引,但我认为这是一个非常麻烦的解决方案。
我不是很熟悉 Regex 或 Spark SQL,所以即使只是 regex 也会很有用。
谢谢
编辑:我想我已经掌握了正则表达式,现在我只需要了解如何使用它。
https:\/\/xxx\.xxxxxx\.com\/xxxxx\/(?:[^0-9\/]+)\/([a-zA-z]*)
我稍微修改了你的正则表达式。正则表达式:
^https:\/\/www\.example\.com\/user=\/(.*?)\/(.*?)(?:\/.*|$)$
它将捕获两组:
- 第 1 组 - 用户名
- 第二组 - 某个名字
您可以使用 regexp_extract
spark 函数来选择正则表达式捕获组。例如
import spark.implicits._
import org.apache.spark.sql.functions.regexp_extract
val df = Seq(
("https://www.example.com/user=/username1/name3/asd"),
("https://www.example.com/user=/username2/name2"),
("https://www.example.com/user=/username3/name1/asd"),
("https://www.example.com/user=")
).toDF("url")
val r = "^https:\/\/www\.example\.com\/user=\/(.*?)\/(.*?)(?:\/.*|$)$"
df.select(
$"url",
regexp_extract($"url", r, 1).as("username"),
regexp_extract($"url", r, 2).as("name")
).show(false)
结果:
+-------------------------------------------------+---------+-----+
|url |username |name |
+-------------------------------------------------+---------+-----+
|https://www.example.com/user=/username1/name3/asd|username1|name3|
|https://www.example.com/user=/username2/name2 |username2|name2|
|https://www.example.com/user=/username3/name1/asd|username3|name1|
|https://www.example.com/user= | | | <- not correct url
+-------------------------------------------------+---------+-----+
P.S。您可以使用 regex101.com 来验证您的正则表达式
我必须创建一个数据框,其中一列中的行应该是我从长 URL 中提取的名称。假设我有以下 url:
https://xxx.xxxxxx.com/xxxxx/y...y/?...?/<irrelevant>
现在不幸的是我不能透露确切的 URLs 但我可以说的是字母 x
包含不变的字符串(即所有 URLs在数据库中包含这些模式并且是已知的),y...y
是一个未知的用户名,长度未知并且可能随每个 URL 而改变 ?...?
是我的名字我对(又是一个长度未知的字符串)感兴趣。之后可能会有多个字符串被 /
分隔,这些字符串没有用。我该怎么做呢?到目前为止,我曾经做过三种不同的 UDF,它们使用子字符串和索引,但我认为这是一个非常麻烦的解决方案。
我不是很熟悉 Regex 或 Spark SQL,所以即使只是 regex 也会很有用。
谢谢
编辑:我想我已经掌握了正则表达式,现在我只需要了解如何使用它。
https:\/\/xxx\.xxxxxx\.com\/xxxxx\/(?:[^0-9\/]+)\/([a-zA-z]*)
我稍微修改了你的正则表达式。正则表达式:
^https:\/\/www\.example\.com\/user=\/(.*?)\/(.*?)(?:\/.*|$)$
它将捕获两组:
- 第 1 组 - 用户名
- 第二组 - 某个名字
您可以使用 regexp_extract
spark 函数来选择正则表达式捕获组。例如
import spark.implicits._
import org.apache.spark.sql.functions.regexp_extract
val df = Seq(
("https://www.example.com/user=/username1/name3/asd"),
("https://www.example.com/user=/username2/name2"),
("https://www.example.com/user=/username3/name1/asd"),
("https://www.example.com/user=")
).toDF("url")
val r = "^https:\/\/www\.example\.com\/user=\/(.*?)\/(.*?)(?:\/.*|$)$"
df.select(
$"url",
regexp_extract($"url", r, 1).as("username"),
regexp_extract($"url", r, 2).as("name")
).show(false)
结果:
+-------------------------------------------------+---------+-----+
|url |username |name |
+-------------------------------------------------+---------+-----+
|https://www.example.com/user=/username1/name3/asd|username1|name3|
|https://www.example.com/user=/username2/name2 |username2|name2|
|https://www.example.com/user=/username3/name1/asd|username3|name1|
|https://www.example.com/user= | | | <- not correct url
+-------------------------------------------------+---------+-----+
P.S。您可以使用 regex101.com 来验证您的正则表达式