正则表达式如何捕获scala中的工作?

时间:2015-08-17 15:21:46

标签: regex scala

以下是一个例子:

object RegexTest {
  def main (args: Array[String]): Unit = {
    val input = "Enjoy this apple 3.14 times"
    val pattern = """.* apple ([\d.]+) times""".r
    val pattern(amountText) = input
    val amount = amountText.toDouble
    println(amount)
  }
}

我明白这是做什么的,但val pattern(amountText) = input实际上是如何运作的?这看起来很奇怪。

2 个答案:

答案 0 :(得分:4)

该行正在做的是调用Regex.unapplySeq(也称为extractor)将input解构为捕获的组列表,然后将每个组绑定到一个新变量。在此特定方案中,预计只会捕获一个组并将其绑定到值amountText

除了验证之外,这有点像幕后发生的事情:

val capturedGroups = pattern.unapplySeq(input)
val amountText = capturedGroups(0)

// And this:
val pattern(a, b, c) = input

// Would be equivalent to this:
val capturedGroups = pattern.unapplySeq(input)
val a = capturedGroups(0)
val b = capturedGroups(1)
val c = capturedGroups(2)

它与提取元组非常相似:

val (a, b) = (2, 3)

甚至模式匹配:

(2,3) match {
  case (a, b) => 
}

在这两种情况下,都会调用Tuple.unapply

答案 1 :(得分:1)

我建议您查看此页面:http://docs.scala-lang.org/tutorials/tour/extractor-objects.html。这是关于提取器的官方教程,这是您正在寻找的模式。

我发现查看来源可以清楚地了解其工作原理:https://github.com/scala/scala/blob/2.11.x/src/library/scala/util/matching/Regex.scala#L243

然后,请注意您的代码val pattern(amountText) = input完全正常,但是,您必须确保输入并确保与正则表达式匹配。

否则,我建议你这样写:

input match { case pattern(amountText) => ... case _ => ... }