2013-02-08 58 views
4

我有一個字符串和正則表達式模式的列表。我想過濾列表中不匹配正則表達式的項目。我使用下面的代碼似乎沒有工作:斯卡拉列表匹配正則表達式

val matching = token.filter(x => regex.pattern.matcher(x).matches) 

其中token是字符串和正則表達式的列表是我想匹配

+3

我認爲這個問題對於SO來說非常好,我很驚訝它沒有評論就關閉了。它所需要的只是一個示例字符串/正則表達式,它是一個完美而緊湊的問題。 –

回答

8

你的代碼應工作格局。你確定你的正則表達式是正確的嗎?

val regex = "a.c".r 
val tokens = List("abc", "axc", "abd", "azc") 
tokens filter (x => regex.pattern.matcher(x).matches) 
//result: List[String] = List(abc, axc, azc) 

編輯:

鑑於你的正則表達式,確保下面的例子符合你的期望:

val regex = """\b[b-df-hj-np-tv-z]*[aeiou]+[b-df-hj-np-tv-z]*\b""".r 

regex.pattern.matcher("good").matches 
//res3: Boolean = true 

regex.pattern.matcher("no good deed").matches 
//res4: Boolean = false 

matches方法會嘗試將整個字符串相匹配。

+0

是我的正則表達式很簡單,「」「\ b [b-df-hj-np-tv-z] * [aeiou] + [b-df-hj -np -tv-z] * \ b」「」。 r –

+0

您是否知道正則表達式會嘗試匹配整個字符串? – 2013-02-08 06:44:29

+0

@ user500592,不匹配整個字符串的好方法是什麼? 'regex.unanchored.pattern.matcher(string).matches'似乎沒有辦法。似乎有必要把'。*'貼在正則表達式的頭部和尾部,這很醜陋。 –

1

你有沒有嘗試過這樣的:

val list = List("abc","efg","") 
val p = java.util.regex.Pattern.compile(".*") 

val matching = list filter { p.matcher(_).matches } 
3

的完整性的另一種選擇:

val words = List("alpha", "bravo", "charlie", "alphie") 
words.filter(_.matches("a.*")) 

res0: List[java.lang.String] = List(alpha, alphie) 
+0

這將爲列表中的每個元素重新生成正則表達式。 –

1

的東西,我已經遇到了麻煩,使用Scala的正則表達式引擎時是.matches將嘗試匹配整個字符串,而不是對每個可能的子字符串進行匹配。

在許多正則表達式引擎,下面的代碼將評估爲比賽:

"alphie".match(/a/)

在Scala中,使用.matches這裏會失敗;它會嘗試將「a」與整個字符串「alphie」進行匹配。但是,如果正則表達式爲/a*/,它將起作用,因爲*字符將匹配零個或多個字符。

如果添加重複正則表達式的符號不是一個選項,該方法findAllIn可能是有用的:

val words = List("alpha", "bravo", "charlie", "alphie") 

val regex = "a.".r         

//returns a tuple with the list item that matched, plus the text that fit the regex 
for { 
    word <- words 
    matches <- regex.findAllIn(word) 
} yield (word,matches) 

注:findAllIn可以多次匹配特定字符串,如果有在字符串中的多個匹配。

+0

是的。比賽意味着匹配!不搜索或找到。 –

+0

我認爲@nimda意識到這一點,但令人驚訝的是,像當前API中不存在'regex.matchesSomewhere(_)'這樣的概念上簡單的概念。 @nimda,一個選項是使用'.unanchored'方法。 –