2014-04-06 59 views
1

我对Scala非常陌生,尤其是令人敬畏的模式匹配。但是,我发现这个代码不起作用。我创建了一个包含匹配词的“词典”,然后我使用了理解,因此每一行都会与词典中的词匹配。Scala模式匹配无法匹配特定字

这是用来创建正则表达式的地图。

val dictionary = Map(
    """will""" -> 1, 
    """going to""" -> 2, 
    """future""" -> 3 
) 

这是主要的for循环:

for (
     ln <- file.getLines(); 
     (word, loc) <- dictionary 
    ){ 
     val regex = word.r 
     ln match { 
     case regex(ln) => {totalLine += 1 
      println("Match detected: " + word) 
      val originalElem = doc.BOWVector(dictionary.get(ln).get) 
      doc.BOWVector.updated(dictionary.get(ln).get, originalElem+1) //vector is updated 
      } 
     case _ => {totalLine += 1} 
     } 
} 

当我使用ln.contains("will")和它的作品!然而,正则表达式不起作用。为什么?

回答

2

靠近一点:

scala> for (ln <- List("I will go"); (word, loc) <- dictionary) { 
    | val r = word.r.unanchored 
    | ln match { case r() => println(s"Yes $word") ; case _ => println(s"No $word") }} 
Yes will 
No going to 
No future 

默认锚定正则表达式是^will$

如果您不想担心捕获组,请使用“序列通配符”。

scala> for (ln <- List("I will go"); (word, loc) <- dictionary) { 
    | val r = word.r.unanchored 
    | ln match { case r(_*) => println(s"Yes $word") ; case _ => println(s"No $word") }} 
Yes will 
No going to 
No future 

scala> val dictionary = Map("wi(l*)" -> 1) 
dictionary: scala.collection.immutable.Map[String,Int] = Map(wi(l*) -> 1) 

scala> for (ln <- List("I will go"); (word, loc) <- dictionary) { 
    | val r = word.r.unanchored 
    | ln match { case r(_*) => println(s"Yes $word") ; case _ => println(s"No $word") }} 
Yes wi(l*) 

scala> for (ln <- List("I will go"); (word, loc) <- dictionary) { 
    | val r = word.r.unanchored 
    | ln match { case r(ells) => println(s"Yes $ells") ; case _ => println(s"No $word") }} 
Yes ll 
+0

谢谢!其实'.unanchored'做了很大的改变,并使这个程序的工作! –

1

的问题是,scala.util.matching.Regex.unapplySeq收益匹配的组

如果正则表达式不包含组(你的情况),在模式匹配它应该在的形式使用:

scala> val regex1 = "foo".r 
regex1: scala.util.matching.Regex = foo 

scala> "foo" match { case regex1() => "match" } 
res0: String = match 

而且随着匹配组是将

scala> val regex2 = "(foo)".r 
regex2: scala.util.matching.Regex = (foo) 

scala> "foo" match { case regex2(group) => s"match $group" } 
res1: String = match foo 

组的数量可以是任意的,但在case声明参数的数目应匹配

scala> val regex3 = "(foo)(\\d)".r 
regex3: scala.util.matching.Regex = (foo)(\d) 

scala> "foo1" match { case regex3(word, digit) => s"match $word $digit" } 
res2: String = match foo 1 

另外,参见实施例为unapplySeq scaladoc

+0

这就是我怀疑的!模式匹配实际上是一个拆箱工具,而不是简单的匹配(case/switch)。 –

+0

Emmm ..出于某种原因,我不知道,该计划仍然无法正常工作。 –