2

我是 Scala 的新手,但有人告诉我“您正在检查“Toronto Raptor”是否 == matchNY。对于以下代码片段@ https://issues.scala-lang.org/browse/SI-7210,我真的不知道为什么“Totonto Raptor”是在for循环中选择的唯一要匹配的字符串使用正则表达式,有人可以向我解释一下吗?
谢谢。大卫

    val matchNY = "^.*New.*$".r

    val teams = List(
        "Toronto Raptor",
        "New York Nets",
        "San Francisco 49ers",
        "Dallas Mavericks"
    )

    for (team <- teams) {
        team match {
            case `matchNY` => println("Go New York.")
            case _ => println("Boo")
        }
    }

注1:这里解释了反引号的用法@http: //alvinalexander.com/scala/scala-unreachable-code-due-to-variable-pattern-message

4

3 回答 3

5

我假设你的意思是

val matchNY = "^.*New.*$".r

而不是^.New.$,如果您希望匹配包含New.

在 Scala 中,一个case语句块可以被认为是一个偏函数序列。

在你的例子中,

case `matchNY` => // ...

翻译成类似的东西:

case x if x == matchNY  => // .. 

所以这将尝试 使用相等性String "Toronto Raptor"Regexp对象匹配:^.*New.*$

"Toronto Raptor" == ("^.*New.*$".r) 

哪个不匹配,因为 aStringRegexpobject 是 2 个不同的东西。

列表中的任何其他Strings 也是如此:

"New York Nets" !=  ("^.*New.*$".r)

哪个也不匹配。在 case 语句中使用正则表达式作为匹配项的方法是:

case matchNY() => // .... Note the ()

其中,在引擎盖下(大致)等同于类似的东西

case x matchNY.unapplySeq(x).isDefined =>  // ...

case 语句中的正则表达式被实现为具有方法的提取器对象unapplySeq。最后一个表达式显示了前一个翻译成的内容。

如果 matchNY 有一个捕获,例如:

val matchNY = "^.*New York\s(.*)$".r

然后你可以用它来提取捕获的匹配:

case matchNY(something) => // 'something' is a String variable 
                           // with value "Nets"

边注

你的例子可以浓缩为

teams foreach { 
   case matchNY() => println("Go New York.")
   case _ => println("Boo")
}
于 2013-03-04T03:18:32.873 回答
4

是的,它工作正常。模式匹配背后的魔法是一种叫做提取器的东西。

如果您深入研究Regex的 ScalaDoc ,您会发现它只是定义unapplySeq的,而不是定义的unapply

这意味着如果您想在模式匹配中使用正则表达式,您应该执行以下操作(注意 matchNY 后的括号):

val matchNY = "^.*New.*$".r

val teams = List(
    "Toronto Raptor",
    "New York Nets",
    "San Francisco 49ers",
    "Dallas Mavericks"
)

for (team <- teams) {
    team match {
        case matchNY() => println("Go New York.")
        case _ => println("Boo")
    }
}

否则,您只是检查列表中的元素是否为== matchNY,这无论如何都不是您想要的。

于 2013-03-04T03:12:47.977 回答
1

在您的 for 循环中,您实际上是在检查列表中的每个项目teams是否等于正则表达式matchNY,并且检查列表中的每个项目而不仅仅是“Toronto Raptor”。这相当于你的 for 循环:

  for (team <- teams) {
    if (team == matchNY) println("Go New York.")
    else println("Boo")
  }

分解为:

  if ("Toronto Raptor" == matchNY) println("Go New York.") else println("Boo")
  if ("New York Nets" == matchNY) println("Go New York.") else println("Boo")
  if ("San Francisco 49ers" == matchNY) println("Go New York.") else println("Boo")
  if ("Dallas Mavericks" == matchNY) println("Go New York.") else println("Boo")

我认为你正在寻找的是如果有东西匹配你是正则表达式。你可以这样做:

  for (team <- teams) {
    matchNY.findFirstMatchIn(team) match {
      case Some(teamMatch) => {
        println("Go New York.")
        println(teamMatch)
      }
      case _ => {
        println("Boo")
        println(team)
      }
    }
  }

打印出来:

Boo
Toronto Raptor
Go New York.
New York Nets
Boo
San Francisco 49ers
Boo
Dallas Mavericks
于 2013-03-04T03:07:13.983 回答