2

私はScalaを初めて使用しますが、「 "Toronto Raptor"==matchNYかどうかを確認している」と言われました。次のコードスニペット@https ://issues.scala-lang.org/browse/SI-7210の場合、forループで一致する文字列が「TotontoRaptor」だけである理由がわかりません。正規表現で、誰かが私にこれを説明してもらえますか?
ありがとう。デビッド

    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  => // .. 

したがって、 equality を使用String "Toronto Raptor"して をRegexpオブジェクトと一致させようとします。^.*New.*$

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

Stringaと a Regexpobject は2つの異なるものであるため、どちらが一致しません。

Stringリスト内の他の s についても同様です。

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

どちらも一致しません。case ステートメントで一致として正規表現を使用する方法は次のとおりです。

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

これは、ボンネットの下で(おおよそ)次のようなものと同等です

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

case ステートメントの正規表現は、メソッドを使用してExtractor オブジェクト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

つまり、パターン マッチングで Regex を使用する場合は、次の手順を実行する必要があります (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 に答える