To define custom matching, you need to define an extractor (an object with an unapply method). Implementing that requires parsing the string. Here's some code that does that using parser combinators:
case class StringAndNumber(string: String, number: Int)
object Test {
def unapply(s: String): Option[StringAndNumber] = Parser(s)
}
object Parser extends scala.util.parsing.combinator.RegexParsers {
def apply(s: String): Option[StringAndNumber] =
parseAll(stringAndNumber, s) match {
case Success(x, _) => Some(x)
case _ => None
}
lazy val stringAndNumber = string ~ number ^^
{ x => StringAndNumber(x._1, x._2) }
lazy val string = "[^0-9]*".r
lazy val number = "[0-9]+".r ^^ { _.toInt }
}
def foo(s: String): String = s match {
case "str" => "str"
case Test(san) => s"${san.string}, $|${san.number}"
case _ => "?"
}
println {
Seq(
foo("str"), // str
prints: foo("str2")"str, // strstr|2, 2?"
println ( Seq("str", "str2", "2str").map(foo("2str"_) // ?
).mkString("\n"", ")
} )