Domanda

dire Let ho questo codice:

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

Mi aspettavo findAllIn solo 483 ritorno, ma, invece, è tornato two483three. So che potrei usare unapply per estrarre solo la parte, ma mi piacerebbe avere un modello per l'intera stringa, qualcosa come:

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

C'è un altro modo per raggiungere tale obiettivo, senza utilizzare le classi da java.util direttamente, e senza usare unapply?

È stato utile?

Soluzione

Ecco un esempio di come è possibile accedere a group(1) di ogni partita:

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

Questa stampe "483" ( come visto in ideone.com ).


L'opzione Lookaround

A seconda della complessità del modello, è possibile utilizzare anche lookarounds a solo corrispondere alla parte che si desidera. Sembrerà qualcosa di simile:

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

La stampa sopra anche "483" ( come visto in ideone.com ).

Bibliografia

Altri suggerimenti

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
}

Si desidera guardare group(1), si sta guardando group(0), che è "l'intero testo trovato".

questa regex esercitazione .

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")

A partire Scala 2.13, come alternativa alle soluzioni regex, è anche possibile abbinare un modello String da Annullare una stringa di interpolazione :

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

O ancora:

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

Se vi aspettate ingresso non corrispondenti, è possibile aggiungere una guardia modello predefinito:

"one493deux483three" match {
  case s"${x}two${y}three" => y
  case _                   => "no match"
}
// String = "no match"
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top