webentwicklung-frage-antwort-db.com.de

Scala-Capture-Gruppe mit Regex

Nehmen wir an, ich habe diesen Code:

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

Ich habe erwartet, dass findAllIn nur 483 zurückgibt, aber stattdessen two483three. Ich weiß, ich könnte unapply verwenden, um nur diesen Teil zu extrahieren, aber ich müsste ein Muster für die gesamte Zeichenfolge haben.

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

Gibt es einen anderen Weg, um dies zu erreichen, ohne die Klassen von Java.util direkt zu verwenden und ohne zu verwenden? 

58
Geo

Hier ist ein Beispiel, wie Sie auf group(1) von jedem Match zugreifen können:

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

Dies druckt "483" ( wie auf ideone.com zu sehen).


Die Lookaround-Option

Abhängig von der Komplexität des Musters können Sie auch Lookarounds verwenden, um only dem gewünschten Abschnitt zuzuordnen. Es wird ungefähr so ​​aussehen: 

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

Das obige druckt auch "483" ( wie auf ideone.com gesehen).

Verweise

87
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
}
27
caiiiycuk

Sie möchten sich group(1) anschauen, Sie schauen sich gerade group(0) an. Dies ist "die gesamte übereinstimmende Zeichenfolge".

Siehe diese Regex-Anleitung .

13
Stephen

Wenn Sie Scala 2.13 als Alternative zu Regex-Lösungen starten, können Sie auch ein String mit einem Muster abgleichen, indem Sie einen String-Interpolator entfernen:

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

Oder auch:

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

Wenn Sie eine nicht übereinstimmende Eingabe erwarten, können Sie einen Standard-Pattern-Guard hinzufügen:

"one493deux483three" match {
  case s"${x}two${y}three" => y
  case _                   => "no match"
}
// String = "no match"
1
Xavier Guihot
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")
1
Gaurav Khare