如何最好地结合Regex组和流来搜索文件



我想扫描一个文件,只找到正则表达式的第一个实例,然后返回与表达式匹配的组的值。

到目前为止,我所有的尝试似乎都非常笨拙,并且涉及到反复使用正则表达式,一次找到目标字符串,然后再次获得组。我也不喜欢在Regexp的开头和结尾使用。*。

有谁能提出一个更优雅的方法吗?

  val DateRegexp = """.*(dddd)-(dd)-(dd).*""".r
  val lineWithDate = scala.io.Source.fromFile(filenameGC).getLines().find{_.matches(""".*(dddd)-(dd)-(dd).*""")  }
  lineWithDate match {
    case Some(result) =>
       result match {
        case DateRegexp(year, month, day) =>
          println(year, month, day)
       }
    case None =>
      println("No date found in file")
  }

经过Cyrille Corpet的大力投入,我现在有…

val DateRegexp = """(dddd)-(dd)-(dd)""".r.unanchored
scala.io.Source.fromFile(filenameGC).getLines().collectFirst{
                   case DateRegexp(y, m, d) => println(y, m, d)}

Regex已经是一个模式(在模式匹配的意义上),所以您可以直接在case语句中使用它:

fileString match {
  case DateRegexp(year, month, day) => println(year, month, day)
}

但是,在您的示例中,.*是贪婪的,它将捕获字符串中模式的最后一次出现。

值得庆幸的是,您可以在模式的开始和结束处删除.*,如果您将其指定为unanchored(意味着它不会尝试将模式与您的整个字符串匹配)。没有贪心的*,现在可以捕获第一个出现:

val regex = """(dddd)-(dd)-(dd)""".r.unanchored
"1987-05-18 2002-12-14" match {
  case regex(y, m, d) => (y.toInt, m.toInt, d.toInt) // (1987, 5, 18)
}

编辑:我意识到我没有解决问题的第一个问题,那就是你没有String,而是Seq[String]。然而,一旦您有了一行的提取器,您只需要在所有行上使用它,直到第一个与collectFirst相关的行,它会找到第一个与给定的case匹配的事件,并对它做一些事情:

(lines: List[String]).collectFirst{
  case regex(y, m, d) => println(y, m, d)
}

相关内容

  • 没有找到相关文章

最新更新