【问题标题】:Scala regex pattern matching with String InterpolationScala 正则表达式模式匹配字符串插值
【发布时间】:2018-12-26 14:39:22
【问题描述】:

从 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?

【问题讨论】:

    标签: regex scala


    【解决方案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
    

    【讨论】:

      【解决方案2】:

      那些参数是组名,在这里不是很有用。

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-05-01
        • 1970-01-01
        • 2015-11-14
        • 2013-08-30
        • 2021-05-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多