Scala中的正则表达式和模式匹配第二部分

时间:2011-10-25 19:40:59

标签: scala pattern-matching

作为this问题

的后续行动

以下是使用捕获编译和运行的一些代码。

val myString = "ACATCGTAGCTGCTAGCTG"

val nucCap = "([ACTG]+)".r

myString match {
   case nucCap(myNuc) => println("dna:"+myNuc)
   case _ => println("not dna")
}

>scala scalaTest.scala 
dna:ACATCGTAGCTGCTAGCTG

这是更简单的代码,没有捕获,无法编译。

val myString = "ACATCGTAGCTGCTAGCTG"

val nuc = "[ACGT]+".r

myString match {
     case nuc => println("dna")
     case _ => println("not dna")
}

>scala scalaTest.scala
scalaTest.scala:7: error: unreachable code

似乎匹配应该返回一个布尔值,无论是否使用捕获。 这是怎么回事?

1 个答案:

答案 0 :(得分:8)

match块中,nuc是模式变量,并未引用封闭范围中的nuc。这使得默认情况无法访问,因为简单模式nuc将匹配任何内容。

nuc上的一对空括号将使语法糖工作并在正则表达式上调用unapplySeq方法:

myString match {
  case nuc() => println("dna")
  case _ => println("not dna")
}

避免此陷阱的一种方法是将nuc重命名为Nuc。以大写字母开头使其成为一个稳定的标识符,因此它引用封闭范围中的Nuc,而不是被编译器视为模式变量。

val Nuc = "[ACGT]+".r
myString match {
  case Nuc => println("dna")
  case _ => println("not dna")
}

以上内容将打印"not dna",因为我们只是将NucmyString进行比较,但它们并不相同。这是一个错误,但可能不那么令人困惑!

在这种情况下,添加括号也会产生预期的效果:

myString match {
  case Nuc() => println("dna")
  case _ => println("not dna")
}
// prints "dna"

顺便说一下,它不是一个返回的布尔值,而是一个Option[List[String]]

scala> nuc.unapplySeq(myString)
res17: Option[List[String]] = Some(List())
scala> nucCap.unapplySeq(myString)
res18: Option[List[String]] = Some(List(ACATCGTAGCTGCTAGCTG))