Spec-Zone.ru › Scala 2.12 Library

Пакет scala.util.matching

пакет matching

Члены типа

класс Regex extends Serializable

Регулярное выражение используется для определения того, соответствует ли строка шаблону, и, если да, для извлечения или преобразования соответствующих частей.

Использование

Этот класс делегирует пакету java.util.regex платформы Java. См. документацию по java.util.regex.Pattern для получения подробностей о синтаксисе регулярных выражений для строк шаблонов.

Экземпляр Regex представляет собой скомпилированный шаблон регулярного выражения. Поскольку компиляция является дорогостоящей операцией, часто используемые Regex должны быть созданы один раз, вне циклов и, возможно, в объекте-компаньоне.

Стандартный способ создания Regex — использование метода r, неявно предоставляемого для строк:

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

Поскольку в многострочных строковых литералах экранирование не обрабатывается, использование тройных кавычек позволяет избежать необходимости экранирования символа обратного слэша, так что "\\d" можно записать как """\d""". Того же результата можно добиться с помощью определенных интерполяторов, таких как raw"\d".r или пользовательского интерполятора r"\d", который также компилирует Regex.

Извлечение

Чтобы извлечь группы захвата при совпадении с 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)

Чтобы выполнить итерацию по совпадающим строкам, используйте 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.")
}

Хотя MatchIterator возвращаемый findAllIn используется как любой Iterator, с чередующими вызовами hasNext и next, hasNext имеет дополнительное побочное действие — продвижение базового соответствия к следующему неиспользованному совпадению. Этот эффект заметен в 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 будут переходить к первому совпадению, если необходимо. Также показано, что hasNext переходит к следующему неиспользованному совпадению, если next уже вернул текущее совпадение.

Текущее 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"
})
Аннотации
@SerialVersionUID()
См. также

java.util.regex.Pattern

трайт UnanchoredRegex extends Regex

Регулярное выражение, которое находит первое совпадение при использовании в совпадении шаблонов.

См. также

Regex#unanchored

Значения членов

объект Regex extends Serializable

© 2002-2019 EPFL, with contributions from Lightbend.
Licensed under the Apache License, Version 2.0.
https://www.scala-lang.org/api/2.12.9/scala/util/matching/index.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API