2015-04-17 57 views
1

我有一个关于Scala部分字符串匹配的快速问题。请看例子:如何剪切从句子集合中匹配的单词?

val s1 = "game of thrones" 
val s2 = Array("thrones videos", "watch game", "game of thrones stuff") 

,我想做一些类型的正则表达式或匹配或contains这样的,在结果应该是一些事情,如:

Array("videos", "watch", "stuff") 

在字符串中的任何字,它在s1中重复被删除。什么是最有效的方式?

我目前正在通过将s1转换为一个正则表达式并将其应用于s2的每一行,但我在使它正常工作时遇到了问题。

回答

2

不知道是最“有效”的方式做到这一点(取决于你的意思高效的),但在这里我们去:

val ss1 = s1.split("\\s").toSet //make a set of the words you have 
//ss1: Array[String] = Array(game, of, thrones) 

val ss2 = s2.map(_.split("\\s").toSet -- ss1).flatten //make a set of words and remove the ones in ss1 
// Array[String] = Array(throne, videos, watch, stuff) 
+1

这可能适合OP的需求,但值得一提的是,由于'Sets'没有排序,你可能会失去's2'中单词的顺序。例如,'(Set(1,2,3,4,5) - Set(1,2))。toList'返回'List(5,3,4)'(并且可以随不同版本的Scala或更新后!) –

3

此使用splitcontainsmapfilter是可以实现的。关键是要首先建立你的过滤词的列表中,通过使用split

val s1Words = s1.split(" ") 

现在,在s2每个字符串,你要使用类似split,滤除出现在s1Words话,然后再将其转换成字符串:

s2.map(_.split(" ").filterNot(s1Words.contains).mkString(" ")) 

你也可以把s1Words成一组,然后使用上Setapply方法,测试对于遏制:

val s1Words = s1.split(" ").toSet 
s2.map(_.split(" ").filterNot(s1Words).mkString(" ")) 

如果s2的话是由一组比其他空间字符分隔符,你可能更愿意使用正则表达式,这样就可以捕捉分离,然后替换它在调用mkString