【问题标题】:Spark filtering with regex使用正则表达式进行火花过滤
【发布时间】:2017-08-13 07:05:45
【问题描述】:

我正在尝试按日期将文件数据过滤为好数据和坏数据,因此将获得 2 个结果文件。从测试文件中,前 4 行需要输入好数据,后 2 行输入坏数据。

我有 2 个问题

  1. 我没有得到任何好的数据,结果文件是空的
  2. 错误的数据结果如下所示 - 仅提取名称字符

    (,C,h) (,J,u) (,T,h) (,J,o) (,N,e) (,B,i)

测试文件

Christopher|Jan 11, 2017|5 
Justin|11 Jan, 2017|5 
Thomas|6/17/2017|5 
John|11-08-2017|5 
Neli|2016|5 
Bilu||5

加载和RDD

scala> val file = sc.textFile("test/data.txt")
scala> val fileRDD = file.map(x => x.split("|"))

正则表达式

scala> val singleReg = """(\w(3))\s(\d+)(,)\s(\d(4))|(\d+)\s(\w(3))(,)\s(\d(4))|(\d+)(\/)(\d+)(\/)(\d(4))|(\d+)(-)(\d+)(-)(\d(4))""".r

开头和结尾的三个 "(双引号)和 .r 在这里重要吗?

过滤器 问题领域

scala> val validSingleRecords = fileRDD.filter(x => (singleReg.pattern.matcher(x(1)).matches))
scala> val badSingleRecords = fileRDD.filter(x => !(singleReg.pattern.matcher(x(1)).matches))

将数组转成字符串

scala> val validSingle = validSingleRecords.map(x => (x(0),x(1),x(2)))
scala> val badSingle = badSingleRecords.map(x => (x(0),x(1),x(2)))

写入文件

scala> validSingle.repartition(1).saveAsTextFile("data/singValid")
scala> badSingle.repartition(1).saveAsTextFile("data/singBad")

更新 1 我上面的正则表达式是错误的,我已将其更新为。在scala中反斜杠是转义字符,所以需要复制

val singleReg = """\\w{3}\\s\\d+,\\s\\d{4}|\\d+\\s\\w{3},\\s\\d{4}|\\d+\/\\d+\/\\d{4}|\\d+-\\d+-\\d{4}""".r

检查了 regex101 上的正则表达式,前 4 行中的日期通过了。

我再次运行了测试,我仍然得到相同的结果。

【问题讨论】:

  • 您能否提及好数据和坏数据的预期输出?
  • 根据正则表达式,前 4 行需要输入好数据,后 2 行需要输入坏数据。
  • 为什么您认为您的 REGEX 匹配前 4 行?你觉得\w(3) 怎么样?如果没有大括号,出现的次数肯定不是 3。你的字面上匹配3 你可以在线测试正则表达式,例如这里regex101.com
  • 我已经更新了正则表达式,正在测试...很快就会更新
  • 向问题添加更新 1

标签: scala apache-spark rdd


【解决方案1】:

代码有两个问题:

  1. 用于分割data.txt 行的字符错误。应该是 '|' 而不是 "|"
  2. 正则表达式singleReg 错误。

正确的代码如下:

加载和RDD

scala> val file = sc.textFile("test/data.txt")
scala> val fileRDD = file.map(x => x.split('|'))

正则表达式

scala> val singleReg = """\w{3}\s\d{2},\s\d{4}|\d{2}\s\w{3},\s\d{4}|\d{1}\/\d{2}\/\d{4}|\d{2}-\d{2}-\d{4}""".r

过滤器

scala> val validSingleRecords = fileRDD.filter(x => (singleReg.pattern.matcher(x(1)).matches))
scala> val badSingleRecords = fileRDD.filter(x => !(singleReg.pattern.matcher(x(1)).matches))

将数组转成字符串

scala> val validSingle = validSingleRecords.map(x => (x(0),x(1),x(2)))
scala> val badSingle = badSingleRecords.map(x => (x(0),x(1),x(2)))

写入文件

scala> validSingle.repartition(1).saveAsTextFile("data/singValid")
scala> badSingle.repartition(1).saveAsTextFile("data/singBad")

上面的代码会给你以下输出-

数据/singValid

(Christopher,Jan 11, 2017,5 )
(Justin,11 Jan, 2017,5 )
(Thomas,6/17/2017,5 )
(John,11-08-2017,5 )

数据/singBad

(Neli,2016,5 )
(Bilu,,5)

【讨论】:

猜你喜欢
  • 2018-06-23
  • 2012-06-08
  • 2015-03-21
  • 1970-01-01
  • 2021-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多