以下是一个例子:
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
实际上是如何运作的?这看起来很奇怪。
答案 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 _ => ...
}