Scala模式匹配无法匹配特定单词

时间:2014-04-06 02:20:03

标签: scala

我对Scala很新,特别是很棒的模式匹配。但是,我觉得这段代码不起作用。我创建了一个包含匹配单词的“字典”,然后我使用了for-comprehension,这样每一行都会与字典中的单词相匹配。

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

  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 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

的示例