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 实例。
问题
从
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 实例。