Scala パターンマッチ
Scalaでは文字列をマッチングさせる場合、match式で処理を書くことができます。
"abcdef" match { case "abcdef" => println("match") case _ => println("not match") }
上記のような直接比較では問題ないのですが、正規表現を使う場合に悩んだので、はまった個所をまとめました。
正規表現を直接書いてもマッチしない
case文に正規表現を記載しても正規表現として認識してくれません。
"abcdef" match { case "^(ab).*" => println("match") // マッチしない case _ => println("not match") }
scala.util.matching.Regexで正規表現を使う
正規表現パターンは文字列に"r"メソッドを適用すれば取得できます。
val matchPattern: Regex = "ab.*".r "abcdef" match { case "^ab.*".r => println("match line1") // 直接書くとコンパイルできない case matchPattern() => println("match line2") // マッチする case _ => println("not match") }
マッチした個所の取得
マッチした個所を取得したい場合、()で囲みグループを使用することにより取得できます。 ただしマッチしたグループすべてが返るため、引数の数とグループ数が合わないとマッチしません。
val matchPattern: Regex = "^(ab).*(ef)$".r "abcdef" match { case matchPattern() => println("match line1") // マッチしない case matchPattern(s1) => println(s"match line2: $s1") // マッチしない case matchPattern(s1, s2) => println(s"match line3 : $s1, $s2") // マッチする case _ => println("not match") }
改行を含んだ文字列との比較
Scalaに限ったことではないですが、文字列に改行が含まれている場合マッチしなくなります。 これは "." が「Match any character except newline(改行を除いた文字)」となっているためです。 "." を "[\\s|\\S]"に変更することによりマッチ可能となります。
expression | match |
---|---|
\\s | Matches whitespace. Equivalent to [\t\n\r\f]. |
\\S | Matches nonwhitespace. |
val matchPattern: Regex = "^(ab).*(ef)[\\s|\\S]*".r "abcdefgh\r\n" match { case matchPattern(s1, s2) => println(s"match: $s1, $s2") case _ => println("not match") }