81

假设我有这个代码:

val string = "one493two483three"
val pattern = """two(\d+)three""".r
pattern.findAllIn(string).foreach(println)

我希望findAllIn只返回483,但相反,它返回了two483three。我知道我可以unapply只提取那部分,但我必须为整个字符串设置一个模式,例如:

 val pattern = """one.*two(\d+)three""".r
 val pattern(aMatch) = string
 println(aMatch) // prints 483

有没有另一种方法来实现这一点,而不java.util直接使用类,并且不使用 unapply?

4

5 回答 5

113

以下是如何访问group(1)每场比赛的示例:

val string = "one493two483three"
val pattern = """two(\d+)three""".r
pattern.findAllIn(string).matchData foreach {
   m => println(m.group(1))
}

这会打印"483"如在 ideone.com 上看到的)。


环视选项

根据模式的复杂性,您还可以使用环视来匹配您想要的部分。它看起来像这样:

val string = "one493two483three"
val pattern = """(?<=two)\d+(?=three)""".r
pattern.findAllIn(string).foreach(println)

上面还打印"483"如在 ideone.com 上看到的)。

参考

于 2010-06-16T06:51:17.820 回答
42
val string = "one493two483three"
val pattern = """.*two(\d+)three.*""".r

string match {
  case pattern(a483) => println(a483) //matched group(1) assigned to variable a483
  case _ => // no match
}
于 2015-11-23T09:13:21.877 回答
20

开始Scala 2.13,作为正则表达式解决方案的替代方案,也可以String通过取消应用字符串插值器来匹配 a :

"one493two483three" match { case s"${x}two${y}three" => y }
// String = "483"

甚至:

val s"${x}two${y}three" = "one493two483three"
// x: String = one493
// y: String = 483

如果您希望输入不匹配,则可以添加默认模式保护:

"one493deux483three" match {
  case s"${x}two${y}three" => y
  case _                   => "no match"
}
// String = "no match"
于 2019-06-26T21:22:59.320 回答
17

你想看group(1),你目前正在看group(0),这是“整个匹配的字符串”。

请参阅此正则表达式教程

于 2010-06-16T05:41:42.640 回答
4
def extractFileNameFromHttpFilePathExpression(expr: String) = {
//define regex
val regex = "http4.*\\/(\\w+.(xlsx|xls|zip))$".r
// findFirstMatchIn/findAllMatchIn returns Option[Match] and Match has methods to access capture groups.
regex.findFirstMatchIn(expr) match {
  case Some(i) => i.group(1)
  case None => "regex_error"
}
}
extractFileNameFromHttpFilePathExpression(
    "http4://testing.bbmkl.com/document/sth1234.zip")
于 2018-07-13T09:51:05.893 回答