问题
从这个答案到相关的 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) }
但是代码无法编译。是否可以定义要在函数内部匹配的正则表达式(或至少是封闭的范围(?
上下文
输入是字符串列表。每个字符串将匹配不同的正则表达式,并且处理方式不同。例如,如果字符串是数字-字母对,则返回数字;如果字符串是 ISO 格式的日期,则返回年份;如果字符串是大写字符串,则返回最后 4 个字符。
输入:List("1,a", "23,zZ", "1990-10-21", "1ab", "", "ABCDEF")
输出:List("1", "23", "1990", "CDEF")
案例数和案例本身可能会更改,因此代码应该能够处理这些更改。
我能够在返回分部函数的封闭作用域中定义正则表达式:
{ 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)
}
只是您需要为每种正则表达式实现新的正则表达式规则实例。