Scala захват группы с использованием регулярных выражений - PullRequest
61 голосов
/ 16 июня 2010

Допустим, у меня есть этот код:

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?

Ответы [ 5 ]

89 голосов
/ 16 июня 2010

Вот пример того, как вы можете получить доступ к 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 ).

Ссылки

29 голосов
/ 23 ноября 2015
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
}
14 голосов
/ 16 июня 2010

Вы хотите посмотреть на group(1), вы в настоящее время смотрите на group(0), что является "всей соответствующей строкой".

См. это руководство по регулярным выражениям .

1 голос
/ 13 июля 2018
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")
0 голосов
/ 27 июня 2019

Начиная с Scala 2.13, в качестве альтернативы решениям регулярных выражений, также возможно сопоставить шаблон с String с помощью , не применяя интерполятор строк :

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