0

问题

this answer to a related Scala Regex Partial Function question,我可以使用以下代码定义一个与正则表达式模式匹配的部分函数:

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

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

语境

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

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

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

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

4

2 回答 2

1

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

{ 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 } },
)
于 2019-09-06T04:54:02.060 回答
0
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 的新实例。

于 2019-09-06T11:19:07.153 回答