我是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
解释了反引号的用法答案 0 :(得分: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)
哪个不匹配,因为String
和Regexp
对象是两个不同的东西。
列表中的任何其他String
也是如此:
"New York Nets" != ("^.*New.*$".r)
哪个也不匹配。在case语句中使用正则表达式作为匹配的方法是:
case matchNY() => // .... Note the ()
其中,引擎盖(大致)等同于
case x matchNY.unapplySeq(x).isDefined => // ...
案例语句中的正则表达式实现为Extractor Objects
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")
}
答案 1 :(得分:4)
是的,它运作正常。模式匹配的神奇背后是extractors。
如果您浏览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
,这不是您想要的。
答案 2 :(得分: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