首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >根据正则表达式提取要在RDD.filter中使用的子串

根据正则表达式提取要在RDD.filter中使用的子串
EN

Stack Overflow用户
提问于 2016-08-24 07:56:22
回答 2查看 798关注 0票数 1

我正在尝试过滤掉一个文本文件的行,该文本文件的第二个列值以列表中的单词开头。

我有这样的列表:

代码语言:javascript
代码运行次数:0
运行
复制
val mylist = ["Inter", "Intra"]

如果我有像这样的行:

代码语言:javascript
代码运行次数:0
运行
复制
Cricket Inter-house

Inter在列表中,因此应该通过RDD.filter操作过滤掉该行。我使用以下正则表达式:

代码语言:javascript
代码运行次数:0
运行
复制
`[A-Za-z0-9]+`

我尝试使用"""[A-Za-z0-9]+""".r来提取子字符串,但结果是在一个非空的迭代器中。

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-24 11:18:12

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

代码语言:javascript
代码运行次数:0
运行
复制
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)
票数 0
EN

Stack Overflow用户

发布于 2016-08-24 08:50:12

filter将删除传递给filter方法的函数返回true的所有内容。因此,正则表达式并不是您想要的。相反,让我们开发一个函数,该函数接受一行并将其与候选字符串进行比较,如果该行中的第二列以候选字符串开头,则返回true

代码语言:javascript
代码运行次数:0
运行
复制
val filterFunction: (String, String) => Boolean =
  (row, candidate) => row.split(" ").tail.head.startsWith(candidate)

我们可以说服自己,使用工作表很容易做到这一点:

代码语言:javascript
代码运行次数:0
运行
复制
// 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

现在剩下的就是在过滤器中使用这个函数了。基本上,对于每一行,我们希望针对候选列表中的每一行测试筛选器。这意味着获取候选列表并“向左折叠”,以根据函数检查其中的每一项。如果任何候选人报告为真,那么我们知道应该从最终结果中过滤掉该行:

代码语言:javascript
代码运行次数:0
运行
复制
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中的行和当前项运行筛选函数的结果进行逻辑或运算。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39112409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档