match regex


In [14]:
val dateNoDay = "2016-08"
val dateWithDay = "2016-08-20"

// these are the patterns (note the starting capital letter)
val YearAndMonth = """(\d{4})-([01][0-9])""".r
val YearMonthAndDay = """(\d{4})-([01][0-9])-([012][0-9])""".r

// this prints: "day provided: it is 20"
dateWithDay match{
  case YearAndMonth(year,month) => println("no day provided")
  case YearMonthAndDay(year,month,day) => println(s"day provided: it is $day")
}


day provided: it is 20
Out[14]:
dateNoDay: String = "2016-08"
dateWithDay: String = "2016-08-20"
YearAndMonth: scala.util.matching.Regex = (\d{4})-([01][0-9])
YearMonthAndDay: scala.util.matching.Regex = (\d{4})-([01][0-9])-([012][0-9])

As with regular case classes, you will get a MatchError if you exhaust your options with matching anything


In [15]:
// this won't match any patterns
val badString = "foo-bar-baz"

// scala.MatchError: foo-bar-baz (of class java.lang.String)
badString match{
  case YearAndMonth(year,month) => println("no day provided")
  case YearMonthAndDay(year,month,day) => println("day provided: it is $day")
}


scala.MatchError: foo-bar-baz (of class java.lang.String)
  ammonite.$sess.cmd14$Helper.<init>(cmd14.sc:4)
  ammonite.$sess.cmd14$.<init>(cmd14.sc:7)
  ammonite.$sess.cmd14$.<clinit>(cmd14.sc:-1)

must use empty parens, even if there are no capturing groups


In [16]:
// groups starting with ?: are "non-capturing" groups
// so this pattern has no capturing groups
val Pattern = """^(?:foo|bar)\.baz""".r

// no matching groups but you must use empty parens
"""foo.baz""" match {
  case Pattern() => "ok" // MUST have parens at the end of Pattern
  case _ => "bleh"
}


Out[16]:
Pattern: scala.util.matching.Regex = ^(?:foo|bar)\.baz
res15_1: String = "ok"

lists


In [1]:
// lets define a list of Ints
val list1:List[Int] = List(1,2,3,4,5,6)

// and then try to pattern match on it
list1 match {
    case list: List[String] => "list of strings"
    case list: List[Int] => "list of ints"
    case _ => "List of unknown type"
}


Out[1]:
list1: List[Int] = List(1, 2, 3, 4, 5, 6)
res0_1: String = "list of strings"

In [1]:
val ints: List[Int] = List(1,2,3,4,5)
val strings: List[String] = List("foo","bar","baz")


ints match{
    case List(_: String, _*) => "it's a list of strings"    
    case List(_: Int, _*) => "it's a list of ints"
}
// "it's a list of ints"


cmd1.sc:5: scrutinee is incompatible with pattern type;
 found   : String
 required: Int
    case List(_: String, _*) => "it's a list of strings"    
                 ^Compilation Failed
Compilation Failed

In [1]:
import scala.reflect.runtime.universe.{TypeTag, typeOf => typeOF}

def processList[T:TypeTag](list: List[T]) = {
    typeOF[T] match {
        case typeOf[List[String]] => "it's a list of strings"
        case typeOf[List[Int]] => "it's a list of ints"
    }
}

val ints: List[Int] = List(1,2,3,4,5)
val strings: List[String] = List("foo","bar","baz")

processList(ints)


cmd1.sc:5: not found: type typeOf
        case typeOf[List[String]] => "it's a list of strings"
             ^cmd1.sc:6: not found: type typeOf
        case typeOf[List[Int]] => "it's a list of ints"
             ^Compilation Failed
Compilation Failed

In [1]:
import scala.reflect.runtime.universe._
...

def processThing[T: TypeTag](thing: Thing[T]) = {
  typeOf[T] match {
    case t if t =:= typeOf[Seq[Int]] => "Thing of Seq[Int]"
    case t if t =:= typeOf[Seq[String]] => "Thing of Seq[String]"
    case t if t =:= typeOf[Int] => "Thing of Int"
    case _ => "Thing of other"
  }
}


cmd1.sc:4: not found: type Thing
def processThing[T: TypeTag](thing: Thing[T]) = {
                                    ^cmd1.sc:5: reference to typeOf is ambiguous;
it is imported twice in the same scope by
import scala.reflect.runtime.universe._
and import _root_.ammonite.repl.ReplBridge.value.{typeOf, show, tprintColorsImplicit, pprinterImplicit, codeColorsImplicit}
  typeOf[T] match {
  ^Compilation Failed
Compilation Failed

In [ ]: