提取基于正则表达式的子字符串在RDD.filter中使用

问题描述:

我想过滤掉第二列值以列表中的单词开头的文本文件的行。提取基于正则表达式的子字符串在RDD.filter中使用

我的列表,如:

val mylist = ["Inter", "Intra"] 

如果我有一排这样的:

Cricket Inter-house 

Inter是在列表中,那么该行应由RDD.filter操作得到过滤掉。我使用正则表达式如下:

`[A-Za-z0-9]+` 

我试着用"""[A-Za-z0-9]+""".r提取子,但结果是在非空迭代。

我的问题是如何访问过滤器操作中的上述结果?

由于"""[A-Za-z0-9]+"""匹配任何单词,因此您需要构造像".* Inter.*".r这样的正则表达式。这里有一些工作的例子,希望它有帮助:

val mylist = List("Inter", "Intra")  
val textRdd = sc.parallelize(List("Cricket Inter-house", "Cricket Int-house", 
            "AAA BBB", "Cricket Intra-house")) 

// map over my list to dynamically construct regular expressions and check if it is within 
// the text and use reduce to make sure none of the pattern exists in the text, you have to 
// call collect() to see the result or take(5) if you just want to see the first five results. 

(textRdd.filter(text => mylist.map(word => !(".* " + word + ".*").r 
         .pattern.matcher(text).matches).reduce(_&&_)).collect()) 

// res1: Array[String] = Array(Cricket Int-house, AAA BBB) 

filter将删除传递给filter方法的函数返回true的所有内容。因此,正则表达式并不完全是你想要的。相反,让我们建立一个函数,它的行,并确定它的候选字符串,并返回true如果该行第二列与候选人开始:

val filterFunction: (String, String) => Boolean = 
    (row, candidate) => row.split(" ").tail.head.startsWith(candidate) 

我们可以说服自己,这工作很容易地使用工作表:

// Test data 
val mylist = List("Inter", "Intra") 
val file = List("Cricket Inter-house", "Boom Shakalaka") 

filterFunction("Cricket Inter-house", "Inter") // true 
filterFunction("Cricket Inter-house", "Intra") // false 
filterFunction("Boom Shakalaka", "Inter") // false 
filterFunction("Boom Shakalaka", "Intra") // false 

现在剩下的就是在过滤器中使用这个功能。实质上,对于每一行,我们都想根据候选列表中的每一行来测试过滤器。这意味着考虑候选人名单和'折叠左'按照功能检查它的每个项目。如果有任何候选人的报告属实,那么我们就知道该行应该被过滤掉的最终结果:

val result = file.filter((row: String) => { 
    !mylist.foldLeft(false)((x: Boolean, candidate: String) => { 
    x || filterFunction(row, candidate) 
    }) 
}) 

// result: List[String] = List(Boom Shakalaka) 

以上可以稍微密集的解压。我们正在向filter方法传递一个函数,该函数接受一行并生成一个布尔值。我们希望该值为true,当且仅当该行不符合我们的标准时。我们已经在filterFunction中嵌入了我们的标准:我们只需要针对mylist中的每个项目组合运行它。

要做到这一点,我们使用foldLeft,它取一个起始值(在这种情况下为false)并迭代遍历列表,更新该起始值并返回最终结果。

要更新该值,我们编写一个函数,将起始值与运行我们的过滤函数的结果对照行和mylist中的当前项进行逻辑或。