Пакет scala.util.matching
пакет matching
Члены типа
класс Regex extends Serializable
трайт UnanchoredRegex extends Regex
Регулярное выражение, которое находит первое совпадение при использовании в совпадении шаблонов.
- См. также
Значения членов
объект 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
Регулярное выражение используется для определения того, соответствует ли строка шаблону, и, если да, для извлечения или преобразования соответствующих частей.
Использование
Этот класс делегирует пакету 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)Чтобы найти все совпадения:
Чтобы выполнить итерацию по совпадающим строкам, используйте
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, представляющем «текущее совпадение».Пример показывает, что методы
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" })java.util.regex.Pattern