Пакет scala.util.matching
пакет matching
Члены типов
класс Regex extends Serializable
трайт UnanchoredRegex extends Regex
Регулярное выражение, которое находит первое соответствие при использовании в шаблоне соответствия.
- См. также
Члены значений
объект Regex extends java.io.Serializable
© 2002-2019 EPFL, with contributions from Lightbend.
Licensed under the Apache License, Version 2.0.
https://www.scala-lang.org/api/2.13.0/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)Чтобы найти все соответствия:
Чтобы проверить, соответствует ли входной текст регулярному выражению:
date.matches("2018-03-01") // true date.matches("Today is 2018-03-01") // false date.unanchored.matches("Today is 2018-03-01") // trueЧтобы итерироваться по сопоставленным строкам, используйте
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