regexscalapartialfunction

Scala Regex Partial Function with Regex defined in Partial Function


Question

From this answer to a related Scala Regex Partial Function question, I am able to define a partial function which matches a regex pattern using the following code:

val regex = "(\\d+),([A-z]+)".r
val input = List("1,a", "23,zZ", "1", "1ab", "")

scala> input collect { case regex(a, b) => (a, b) }
res2: List[(String, String)] = List((1,a), (23,zZ))

The first line defines the regex while the second line defines the input. Is it possible that I move the definition of the regex to be inside the partial function? I have tried doing:

scala> input collect { val regex = "(\\d+),([A-z]+)".r; case regex(a, b) => (a, b) }

But the code will not compile. Is it possible to define the regex to be matched inside the function (or at least scope enclosed)?

Context

The input is a list of strings. Each string would match a different regex and would be handled differently. For example, if the string is a number-alphabets pair, return the number; if the string is a date in ISO format, return the year; if the string is an uppercase string, return the last 4 characters.

Input: List("1,a", "23,zZ", "1990-10-21", "1ab", "", "ABCDEF")

Output: List("1", "23", "1990", "CDEF")

The number of cases and the cases themselves could change, so the code should be able to handle those changes.


Solution

  • I was able to define the regex in an enclosed scope that returns the partial function:

    { val regex = "(\\d+),([A-z]+)".r; { case regex(a, _*) => a } }
    

    The partial function can be used as:

    val input = List("1,a", "23,zZ", "1991-12-31", "1ab", "")
    val matchers: List[PartialFunction[String, String]] = List(
      { val regex = "(\\d{4})-(\\d{2})-(\\d{2})".r; { case regex(a, _*) => a } },
      { val regex = "(\\d+),([A-z]+)".r; { case regex(a, _*) => a } },
      { val regex = "([A-Z]+)".r; { case regex(a) => a takeRight 4 } },
    )