从Scala 2.10开始,我们可以像这样使用StringContext定义新方法r:
implicit class RegexContext(sc: StringContext) {
def r = new Regex(sc.parts.mkString, sc.parts.tail.map(_ => "x"): _*)
}
然后,我们可以在case关键字之后轻松定义正则表达式模式,如下所示:
"123" match {
case r"\d+" => true
case _ => false
}
我不清楚哪个隐式类RegexContext
内部的实现方式
有人可以向我解释方法r
的实现,尤其是sc.parts.tail.map(_ => "x"): _*
的实现吗?
该实现取自How to pattern match using regular expression in Scala?
答案 0 :(得分:1)
这些args是组名,在这里不是很有用。
scala 2.13.0-M5> implicit class R(sc: StringContext) { def r = sc.parts.mkString.r }
defined class R
scala 2.13.0-M5> "hello" match { case r"hell.*" => }
比较:
scala 2.13.0-M5> implicit class R(sc: StringContext) { def r = sc.parts.mkString("(.*)").r }
defined class R
scala 2.13.0-M5> "hello" match { case r"hell$x" => x }
res5: String = o
答案 1 :(得分:1)
Regex
构造函数带有两个参数。
新的正则表达式(正则表达式:字符串,组名:字符串*)
groupNames
参数是一个变量,因此它(它们)实际上是可选的,在这种情况下,应该将其保留为空,因为groupNames
代码几乎没有用。
让我们回顾一下groupNames
应该做什么。我们将从没有groupNames
开始。
val rx = new Regex("~(A(.)C)~") // pattern with 2 groups, no group names
rx.findAllIn("~ABC~").group(0) //res0: String = ~ABC~
rx.findAllIn("~ABC~").group(1) //res1: String = ABC
rx.findAllIn("~ABC~").group(2) //res2: String = B
rx.findAllIn("~ABC~").group(3) //java.lang.IndexOutOfBoundsException: No group 3
现在使用groupNames
。
val rx = new Regex("~(A(.)C)~", "x", "y", "z") // 3 groups named
rx.findAllIn("~ABC~").group("x") //res0: String = ABC
rx.findAllIn("~ABC~").group("y") //res1: String = B
rx.findAllIn("~ABC~").group("z") //java.lang.IndexOutOfBoundsException: No group 3
那sc.parts.tail.map(_ => "x"): _*
为什么这么没用?首先是因为创建的名称数量与模式中的组数量无关,而且还因为它为指定的每个名称使用相同的字符串"x"
。该名称仅对最后一个命名的组有用。
val rx = new Regex("~(A(.)C)~", "x", "x") // 2 groups named
rx.findAllIn("~ABC~").group("x") //res0: String = B (i.e. group(2))
...和...
val rx = new Regex("~(A(.)C)~", "x", "x", "x") // 3 groups named
rx.findAllIn("~ABC~").group("x") //java.lang.IndexOutOfBoundsException: No group 3