当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Scala matching.Regex用法及代码示例


@SerialVersionUID (-2094783597747625537L)

用法 一

class Regex extends Serializable

正则表达式用于确定字符串是否与模式匹配,如果匹配,则提取或转换匹配的部分。

用法

此类委托给 Java 平台的 java.util.regex 包。有关模式字符串的正则表达式语法的详细信息,请参阅java.util.regex.Pattern 的文档。

Regex 的实例表示已编译的正则表达式模式。由于编译成本高昂,因此经常使用的Regex es 应该在循环之外构建一次,并且可能在伴随对象中构建。

创建 Regex 的规范方法是使用为字符串隐式提供的方法 r

val date = raw"(\d{4})-(\d{2})-(\d{2})".r

由于在多行字符串文字中不处理转义,因此使用三引号避免了必须转义反斜杠字符,因此 "\\d" 可以写成 """\d""" 。使用某些插值器可以实现相同的结果,例如 raw"\d".r 或同时编译 Regex 的自定义插值器 r"\d"

萃取

要在匹配 Regex 时提取捕获组,请将其用作模式匹配中的提取器:

"2004-01-20" match {
  case date(year, month, day) => s"$year was a good year for PLs."
}

要仅检查 Regex 是否匹配,忽略任何组,请使用序列通配符:

"2004-01-20" match {
  case date(_*) => "It's a date!"
}

这是有效的,因为 Regex 提取器会生成一系列字符串。仅从日期中提取年份也可以用序列通配符表示:

"2004-01-20" match {
  case date(year, _*) => s"$year was a good year for PLs."
}

在模式匹配中,Regex 通常匹配整个输入。但是,未锚定的 Regex 会在输入中的任何位置找到该模式。

val embeddedDate = date.unanchored
"Date: 2004-01-20 17:25:18 GMT (10 years, 28 weeks, 5 days, 17 hours and 51 minutes ago)" match {
  case embeddedDate("2004", "01", "20") => "A Scala is born."
}

查找匹配项

要查找或替换模式的匹配项,请使用各种查找和替换方法。对于每种方法,都有一个用于处理匹配字符串的版本和另一个用于处理Match 对象的版本。

例如,与前面的示例一样,与未锚定的 Regex 的模式匹配也可以使用 findFirstMatchIn 来完成。 findFirst 方法返回一个 Option 如果找到匹配项则为非空,如果没有匹配项则返回 None

val dates = "Important dates in history: 2004-01-20, 1958-09-05, 2010-10-06, 2011-07-15"
val firstDate = date.findFirstIn(dates).getOrElse("No date found.")
val firstYear = for (m <- date.findFirstMatchIn(dates)) yield m.group(1)

要查找所有匹配项:

val allYears = for (m <- date.findAllMatchIn(dates)) yield m.group(1)

要检查输入是否与正则表达式匹配:

date.matches("2018-03-01")                     // true
date.matches("Today is 2018-03-01")            // false
date.unanchored.matches("Today is 2018-03-01") // true

要遍历匹配的字符串,请使用 findAllIn ,它返回一个特殊的迭代器,可以查询最后一个匹配的 MatchData

val mi = date.findAllIn(dates)
while (mi.hasNext) {
  val d = mi.next
  if (mi.group(1).toInt < 1960) println(s"$d: An oldie but goodie.")
}

尽管 findAllIn 返回的 MatchIterator 与任何 Iterator 一样使用,交替调用 hasNextnext ,但 hasNext 具有将底层匹配器推进到下一个未使用匹配的附加副作用。此效果在代表"current match" 的MatchData 中可见。

val r = "(ab+c)".r
val s = "xxxabcyyyabbczzz"
r.findAllIn(s).start    // 3
val mi = r.findAllIn(s)
mi.hasNext              // true
mi.start                // 3
mi.next()               // "abc"
mi.start                // 3
mi.hasNext              // true
mi.start                // 9
mi.next()               // "abbc"

该示例显示 MatchData 上的方法(例如 start)将在必要时前进到第一个匹配项。如果next 已经返回当前匹配,它还显示hasNext 将前进到下一个未使用的匹配。

当前的MatchData 可以使用matchData 方法捕获。或者,findAllMatchIn 返回一个 Iterator[Match] ,其中迭代器和它已经生成的 Match 对象之间没有交互。

请注意,findAllIn 会查找不重叠的匹配项。 (有关更多示例,请参阅findAllIn。)

val num = raw"(\d+)".r
val all = num.findAllIn("123").toList  // List("123"), not List("123", "23", "3")

替换文本

文本替换可以无条件执行,也可以根据当前匹配执行:

val redacted    = date.replaceAllIn(dates, "XXXX-XX-XX")
val yearsOnly   = date.replaceAllIn(dates, m => m.group(1))
val months      = (0 to 11).map { i => val c = Calendar.getInstance; c.set(2014, i, 1); f"$c%tb" }
val reformatted = date.replaceAllIn(dates, _ match { case date(y,m,d) => f"${months(m.toInt - 1)} $d, $y" })

Match 与创建它的 Regex 匹配的模式不会重新应用 Regex 。在 reformatted 的表达式中,每个 date 匹配计算一次。但是可以将 Regex 应用于由不同模式产生的 Match

val docSpree = """2011(?:-\d{2}){2}""".r
val docView  = date.replaceAllIn(dates, _ match {
  case docSpree() => "Historic doc spree!"
  case _          => "Something else happened"
})

值参数:

groupNames

捕获组中从名称到索引的映射

pattern

编译的模式

也可以看看:

伴生:

object

源码:

Regex.scala

用法 二

object Regex

该对象定义了说明正则表达式匹配和辅助对象的内部类。

伴生:

class

源码:

Regex.scala

相关用法


注:本文由纯净天空筛选整理自scala-lang.org大神的英文原创作品 matching.Regex。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。