SparkSQL 使用正则表达式拆分
SparkSQL split using Regex
我正在尝试使用正则表达式将一行拆分为一个数组。
我的行包含一个 apache 日志,我希望使用 sql.
进行拆分
我尝试了 split 和 array 函数,但没有。
Select split('10.10.10.10 - - [08/Sep/2015:00:00:03 +0000] "GET /index.html HTTP/1.1" 206 - - "Apache-HttpClient" -', '^([^ ]+) ([^ ]+) ([^ ]+) \[([^\]]+)\] "([^"]+)" \d+ - - "([^"]+)".*')
;
我需要一个包含 6 个元素的数组
谢谢
SPLIT
函数,正如您猜到的那样,根据模式拆分字符串。由于您提供的模式字符串与整个输入相匹配,因此 return 没有任何意义。因此是一个空数组。
import org.apache.spark.sql.functions.{regexp_extract, array}
val pattern = """^([^ ]+) ([^ ]+) ([^ ]+) \[([^\]]+)\] "([^"]+)" \d+ - - "([^"]+)".*"""
val df = sc.parallelize(Seq((
1L, """10.10.10.10 - - [08/Sep/2015:00:00:03 +0000] "GET /index.html HTTP/1.1" 206 - - "Apache-HttpClient" -"""
))).toDF("id", "log")
这里需要的是regex_extract
:
val exprs = (1 to 6).map(i => regexp_extract($"log", pattern, i).alias(s"_$i"))
df.select(exprs:_*).show
// +-----------+---+---+--------------------+--------------------+-----------------+
// | _1| _2| _3| _4| _5| _6|
// +-----------+---+---+--------------------+--------------------+-----------------+
// |10.10.10.10| -| -|08/Sep/2015:00:00...|GET /index.html H...|Apache-HttpClient|
// +-----------+---+---+--------------------+--------------------+-----------------+
或者例如一个 UDF:
val extractFromLog = udf({
val ip = new Regex(pattern)
(s: String) => s match {
// Lets ignore some fields for simplicity
case ip(ip, _, _, ts, request, client) =>
Some(Array(ip, ts, request, client))
case _ => None
}
})
df.select(extractFromLog($"log"))
我正在尝试使用正则表达式将一行拆分为一个数组。 我的行包含一个 apache 日志,我希望使用 sql.
进行拆分我尝试了 split 和 array 函数,但没有。
Select split('10.10.10.10 - - [08/Sep/2015:00:00:03 +0000] "GET /index.html HTTP/1.1" 206 - - "Apache-HttpClient" -', '^([^ ]+) ([^ ]+) ([^ ]+) \[([^\]]+)\] "([^"]+)" \d+ - - "([^"]+)".*') ;
我需要一个包含 6 个元素的数组
谢谢
SPLIT
函数,正如您猜到的那样,根据模式拆分字符串。由于您提供的模式字符串与整个输入相匹配,因此 return 没有任何意义。因此是一个空数组。
import org.apache.spark.sql.functions.{regexp_extract, array}
val pattern = """^([^ ]+) ([^ ]+) ([^ ]+) \[([^\]]+)\] "([^"]+)" \d+ - - "([^"]+)".*"""
val df = sc.parallelize(Seq((
1L, """10.10.10.10 - - [08/Sep/2015:00:00:03 +0000] "GET /index.html HTTP/1.1" 206 - - "Apache-HttpClient" -"""
))).toDF("id", "log")
这里需要的是regex_extract
:
val exprs = (1 to 6).map(i => regexp_extract($"log", pattern, i).alias(s"_$i"))
df.select(exprs:_*).show
// +-----------+---+---+--------------------+--------------------+-----------------+
// | _1| _2| _3| _4| _5| _6|
// +-----------+---+---+--------------------+--------------------+-----------------+
// |10.10.10.10| -| -|08/Sep/2015:00:00...|GET /index.html H...|Apache-HttpClient|
// +-----------+---+---+--------------------+--------------------+-----------------+
或者例如一个 UDF:
val extractFromLog = udf({
val ip = new Regex(pattern)
(s: String) => s match {
// Lets ignore some fields for simplicity
case ip(ip, _, _, ts, request, client) =>
Some(Array(ip, ts, request, client))
case _ => None
}
})
df.select(extractFromLog($"log"))