SparkSQL使用Regex进行拆分



我正试图使用正则表达式将一行拆分为一个数组。我的行包含一个apache日志,我希望使用sql进行拆分。

我试过分割和数组函数,但没有。

选择拆分('10.10.10.10-[08/Sep/2015:0:00:03+0000]"GET/index.html HTTP/1.1"206-"Apache HttpClient"-','^([^]+(([^]+(([^]+;

我期待一个有6个元素的阵列

感谢

正如您所猜测的,

SPLIT函数在模式上拆分字符串。由于您提供的模式字符串与整个输入匹配,因此不需要返回任何内容。因此是一个空数组。

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"))

相关内容

  • 没有找到相关文章

最新更新