【问题标题】:Pattern matching - spark scala RDD模式匹配 - spark scala RDD
【发布时间】:2016-03-06 11:13:38
【问题描述】:

我是来自 R 背景的 Spark 和 Scala 新手。经过几次 RDD 转换后,我得到了一个类型为 RDD 的 RDD

Description: RDD[(String, Int)]

现在我想在字符串 RDD 上应用正则表达式并从字符串中提取子字符串并在新列中添加子字符串。

输入数据:

BMW 1er Model,278
MINI Cooper Model,248

我正在寻找的输出:

   Input                  |  Brand   | Series      
BMW 1er Model,278,          BMW ,        1er        
MINI Cooper Model ,248      MINI ,      Cooper

其中 Brand 和 Series 是从 String RDD 新计算的子字符串

到目前为止我做了什么。

我可以使用正则表达式为字符串实现这一点,但我可以应用到所有行。

 val brandRegEx = """^.*[Bb][Mm][Ww]+|.[Mm][Ii][Nn][Ii]+.*$""".r //to look for BMW or MINI

那我就可以用了

brandRegEx.findFirstIn("hello this mini is bmW testing")

但是如何将它用于 RDD 的所有行并应用不同的正则表达式来实现如上的输出。

我读到了这段代码 sn-p,但不知道怎么写。

val brandRegEx = """^.*[Bb][Mm][Ww]+|.[Mm][Ii][Nn][Ii]+.*$""".r

def getBrand(Col4: String) : String = Col4 match {
    case brandRegEx(str)  =>  
    case _ => ""
    return 'substring
}

任何帮助将不胜感激!

谢谢

【问题讨论】:

  • 能否详细说明这里的问题是什么?正则表达式、模式匹配或 RDD 转换?
  • @zero323 :抱歉,如果问题不可读。基本上我想使用正则表达式在字符串中进行模式匹配。这是在 Spark-scala RDD 中。

标签: regex scala apache-spark pattern-matching rdd


【解决方案1】:

要将您的正则表达式应用于 RDD 中的每个项目,您应该使用 RDD map 函数,该函数使用某个函数(在这种情况下,一个 Partial Function 以便提取到两个部分)转换 RDD 中的每一行组成每一行的元组):

import org.apache.spark.{SparkContext, SparkConf}

object Example extends App {

  val sc = new SparkContext(new SparkConf().setMaster("local").setAppName("Example"))

  val data = Seq(
    ("BMW 1er Model",278),
    ("MINI Cooper Model",248))

  val dataRDD = sc.parallelize(data)

  val processedRDD = dataRDD.map{
    case (inString, inInt) =>
      val brandRegEx = """^.*[Bb][Mm][Ww]+|.[Mm][Ii][Nn][Ii]+.*$""".r
      val brand = brandRegEx.findFirstIn(inString)
      //val seriesRegEx = ...
      //val series = seriesRegEx.findFirstIn(inString)
      val series = "foo"
      (inString, inInt, brand, series)
  }

  processedRDD.collect().foreach(println)
  sc.stop()
}

请注意,我认为您的正则表达式存在一些问题,并且您还需要一个正则表达式来查找系列。此代码输出:

(BMW 1er Model,278,BMW,foo)
(MINI Cooper Model,248,NOT FOUND,foo)

但是,如果您根据需要更正正则表达式,您可以将它们应用到每一行。

【讨论】:

  • 感谢您的快速回复。我也以同样的方式接近。我看到我的正则表达式不正确。我将尝试更正它并在此处发布我的解决方案。
  • 使用findFirstIn(inString) 我不能只得到我需要的子字符串。例如:如果我的输入字符串是 Model BMW 5seriesfindFirstIn(inString) 还给我返回前缀“Model BMW”。你能告诉我要使用哪个功能吗? findFirstIn 绝对不会给出刚刚的 Substring
  • 看看我的示例代码,它确实提取了子字符串,例如“宝马”。另请注意,“Model BMW”实际上是一个子字符串,而不是您想要的子字符串。问题在于您的正则表达式不够具体。
【解决方案2】:

您好,我只是在寻找另一个问题并得到了这个问题。上面的问题可以用正常的变换来解决。

val a=sc.parallelize(collection)
a.map{case (x,y)=>(x.split (" ")(0)+" "+x.split(" ")(1))}.collect

【讨论】:

    猜你喜欢
    • 2019-05-26
    • 1970-01-01
    • 2015-10-31
    • 2018-09-29
    • 2016-05-17
    • 2021-12-17
    • 2020-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多