【问题标题】:Parse an f-style interpolated string to recover arguments解析 f 样式的插值字符串以恢复参数
【发布时间】:2015-05-13 05:40:03
【问题描述】:

为 f 样式字符串插值创建补码的最佳方法是什么,即解析格式化字符串中的参数/数字的方法?

例如

val format = "frame%04d.png"
val i = 123
val out = f"frame$i%04d.png"
assert(out == "frame0123.png")

def parse(s: String, pat: String): Int = ???

val j = parse(out, format)
assert(j == 123)

我知道我可以手动构造一个正则表达式,我只是想知道是否有一个使用 f 样式插值字符串的通用方法。

我希望得到一些简单的东西,例如:

val f"frame$j%04d.png" = out

但是

错误:宏方法 f 不是案例类,也没有 unapply/unapplySeq 成员

【问题讨论】:

    标签: scala parsing string-formatting string-interpolation


    【解决方案1】:

    我发现 this nice post 关于使用插值器作为模式匹配器,所以这是你的起点:

    object StringMatcher {
      val ZeroFillDec = "%0(\\d+)d(.*)".r
      val SimpleDec = "%(\\d+)d(.*)".r
      val String = "%s(.*)".r
    
      def patternize(part: String) = part match {
        case ZeroFillDec(len, rest) => f"(\\d{${len.toInt}})$rest"
        case SimpleDec(len, rest) => f"(\\d{1,${len.toInt}})$rest"
        case String(rest) => f"(.*)$rest"
        case rest => f"(.*)$rest"
      }
    }
    
    implicit class StringMatcher(sc: StringContext) {
    
      import StringMatcher.patternize
    
      object pat {
        def unapplySeq(s: String): Option[Seq[String]] = {
          val re = (sc.parts.head ++ (sc.parts.tail map patternize)).mkString.r
          re.unapplySeq(s)
        }
      }
    }
    

    使用它,代码

    val out = "frame0123_023.png"
    val pat"frame$j%04d_$i%03d.png" = out
    

    分配

    j: String = 0123
    i: String = 023
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-30
      • 2020-05-24
      • 2020-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-18
      • 2021-04-23
      相关资源
      最近更新 更多