Scala 正则表达式部分函数与部分函数中定义的正则表达式

Scala Regex Partial Function with Regex defined in Partial Function

问题

到一个相关的 Scala 正则表达式部分函数问题,我可以使用以下代码定义一个匹配正则表达式模式的部分函数:

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))

第一行定义正则表达式,第二行定义输入。是否可以将正则表达式的定义移动到部分函数内?我试过这样做:

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

但是代码无法编译。是否可以在函数内定义要匹配的正则表达式(或至少包含范围)?

上下文

输入是一个字符串列表。每个字符串将匹配不同的正则表达式,并以不同方式处理。例如,如果字符串是数字-字母对,则 return 数字;如果字符串是 ISO 格式的日期,return 年份;如果字符串是大写字符串,则 return 最后 4 个字符。

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

输出:List("1", "23", "1990", "CDEF")

案例数量和案例本身可能会发生变化,因此代码应该能够处理这些变化。

我能够在 returns 部分函数的封闭范围内定义正则表达式:

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

部分函数可以用作:

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 } },
)
import scala.util.matching.Regex

trait RegexRule {
  val rule: Regex

  def apply(): PartialFunction[String, String] = {
    case rule(a, _*) => a
  }
}

object RegexRule {

  def createMatcher(l: Seq[RegexRule]): PartialFunction[String, String] =
    l.map(_.apply()).reduce(_.orElse(_))
}

object DateRegexRule extends RegexRule {
  val rule: Regex = "(\d{4})-(\d{2})-(\d{2})".r
}

object NumberRegexRule extends RegexRule {
  val rule: Regex = "(\d+),([A-z]+)".r
}

object AlphabeticRegexRule extends RegexRule {
  val rule: Regex = "([A-Z]+)".r
  override def apply(): PartialFunction[String, String] =
    super.apply().andThen(_.takeRight(4))

}

object PartialFunctionWithRegex extends App {

  val input = List("1,a", "23,zZ", "1991-12-31", "1ab", "", "ABCEDT")

  val regexRules: Seq[RegexRule] =
    Seq(DateRegexRule, NumberRegexRule, AlphabeticRegexRule)

  val matchers: PartialFunction[String, String] =
    RegexRule.createMatcher(regexRules)

  val result = input.collect(matchers)
  println(result)
  //List(1, 23, 1991, CEDT)

}

您只需要为每种正则表达式实现新的 RegexRule 实例。