Spec-Zone.ru › Scala 3.1

Класс scala.util.matching.Regex

Объект-компаньон • Исходный код

@SerialVersionUID(-2094783597747625537L)
class 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)

Чтобы проверить, соответствует ли входное значение регулярному выражению:

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, представляющем "текущее совпадение".

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"
})
Параметры значения
groupNames

Сопоставление имен с индексами в группах захвата

pattern

Скомпилированный шаблон

См. также

java.util.regex.Pattern

Надтипы
Интерфейс Serializable
Класс Object
Интерфейс Matchable
Класс Any
Известные подтипы
Интерфейс UnanchoredRegex
Тип экземпляра
Regex

Конструкторы

Исходный код
def this(regex: String, groupNames: String*)

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

Если имена групп заданы, они могут быть использованы таким образом:

val namedDate  = new Regex("""(\d\d\d\d)-(\d\d)-(\d\d)""", "year", "month", "day")
val namedYears = for (m <- namedDate findAllMatchIn dates) yield m group "year"

Встроенные имена групп предпочтительнее имён групп, переданных в конструктор, при получении совпавших групп по имени. Имена групп, переданные в конструктор, следует считать устаревшими.

В этом конструкторе не поддерживаются флаги опций, которые должны быть переданы в строку шаблона в качестве встроенных флагов: (?idmsuxU).

Параметры значения
groupNames

Имена групп захвата.

regex

Регулярное выражение для компиляции.

Конкретные методы

Исходный код
def anchored: Regex

Исходный код
def findAllIn(source: CharSequence): MatchIterator

Возвращает все неперекрывающиеся совпадения этого Regex в заданной последовательности символов в виде scala.util.matching.Regex.MatchIterator, который является специальным scala.collection.Iterator, возвращающим совпадающие строки, но также может быть запрошен для получения дополнительных данных о последнем совпадении, таких как группы захвата и начальная позиция.

MatchIterator также может быть преобразован в итератор, возвращающий объекты типа scala.util.matching.Regex.Match, как обычно возвращается findAllMatchIn.

В случае потенциальных перекрывающихся совпадений возвращается первое возможное совпадение, за которым следует следующее совпадение, следующее за входными данными, использованными первым совпадением:

val hat  = "hat[^a]+".r
val hathaway = "hathatthattthatttt"
val hats = hat.findAllIn(hathaway).toList                     // List(hath, hattth)
val pos  = hat.findAllMatchIn(hathaway).map(_.start).toList   // List(0, 7)

Для возвращения перекрывающихся совпадений можно сформулировать регулярное выражение с предпроверкой (?=) , которое не потребляет область перекрытия.

val madhatter = "(h)(?=(at[^a]+))".r
val madhats   = madhatter.findAllMatchIn(hathaway).map {
  case madhatter(x,y) => s"$x$y"
}.toList                                       // List(hath, hatth, hattth, hatttt)

Попытка получить информацию о совпадении после исчерпания итератора приводит к java.lang.IllegalStateException. См. scala.util.matching.Regex.MatchIterator для получения подробностей.

Параметры значения
source

Текст, для которого ищется совпадение.

Возвращает

scala.util.matching.Regex.MatchIterator совпадающих подстрок.

Пример
for (words <- """\w+""".r findAllIn "A simple example.") yield words

Исходный код
def findAllMatchIn(source: CharSequence): Iterator[Match]

Возвращает все неперекрывающиеся совпадения этого регулярного выражения в заданной последовательности символов в виде scala.collection.Iterator объектов scala.util.matching.Regex.Match.

Параметры значения
source

Текст, для которого ищется совпадение.

Возвращает

scala.collection.Iterator объектов scala.util.matching.Regex.Match для всех совпадений.

Пример
for (words <- """\w+""".r findAllMatchIn "A simple example.") yield words.start

Исходный код
def findFirstIn(source: CharSequence): Option[String]

Возвращает необязательную первую строку, соответствующую этому Regex в заданной последовательности символов, или None, если совпадение отсутствует.

Параметры значения
source

Текст, для которого ищется совпадение.

Возвращает

Объект scala.Option первой совпадающей строки в тексте.

Пример
"""\w+""".r findFirstIn "A simple example." foreach println // prints "A"

Исходный код
def findFirstMatchIn(source: CharSequence): Option[Match]

Возвращает необязательное первое совпадение этого Regex в заданной последовательности символов, или None, если оно не существует.

Если совпадение успешно, то scala.util.matching.Regex.Match можно использовать для получения дополнительной информации.

Параметры
source

Текст для поиска совпадений.

Возвращаемое значение

Объект scala.Option типа scala.util.matching.Regex.Match первого совпадения в тексте.

Пример
("""[a-z]""".r findFirstMatchIn "A simple example.") map (_.start) // returns Some(2), the index of the first match in the text

Исходный код
def findPrefixMatchOf(source: CharSequence): Option[Match]

Возвращает необязательное совпадение этого Regex в начале заданной последовательности символов, или None, если оно не соответствует ни одному префиксу последовательности.

В отличие от findFirstMatchIn, этот метод возвращает совпадение только в начале входных данных.

Параметры
source

Текст для поиска совпадений.

Возвращаемое значение

Объект scala.Option типа scala.util.matching.Regex.Match совпавшего фрагмента.

Пример
"""\w+""".r findPrefixMatchOf "A simple example." map (_.after) // returns Some(" simple example.")

Исходный код
def findPrefixOf(source: CharSequence): Option[String]

Возвращает необязательное совпадение этого Regex в начале заданной последовательности символов, или None, если оно не соответствует ни одному префиксу последовательности.

В отличие от findFirstIn, этот метод возвращает совпадение только в начале входных данных.

Параметры
source

Текст для поиска совпадений.

Возвращаемое значение

Объект scala.Option совпавшего префикса.

Пример
"""\p{Lower}""".r findPrefixOf "A simple example." // returns None, since the text does not begin with a lowercase letter

Исходный код
def matches(source: CharSequence): Boolean

Возвращает true, если это Regex соответствует заданной последовательности символов.

Подобно экстрактору, этот метод учитывает привязку.

Параметры
source

Текст для поиска совпадений.

Возвращаемое значение

true, если и только если source соответствует этому Regex.

См. также

Regex#unanchored

Пример
"""\d+""".r matches "123" // returns true

Исходный код
def regex: String

Исходный код
def replaceAllIn(target: CharSequence, replacement: String): String

Заменяет все совпадения строкой.

В строке замены знак доллара ($) за которым следует число будет интерпретироваться как ссылка на группу в шаблоне совпадения, числа от 1 до 9 соответствуют первым девяти группам, а 0 — всему совпадению. Любой другой символ является ошибкой. Символ обратной косой черты (\) будет интерпретироваться как символ экранирования и может использоваться для экранирования знака доллара. Для экранирования этих символов используйте Regex.quoteReplacement.

Параметры
replacement

Строка, которая заменит каждое совпадение.

target

Строка для поиска совпадений.

Возвращаемое значение

Результирующая строка.

Пример
"""\d+""".r replaceAllIn ("July 15", "<NUMBER>") // returns "July <NUMBER>"

Исходный код
def replaceAllIn(target: CharSequence, replacer: Match => String): String

Заменяет все совпадения с использованием функции замены. Функция замены принимает scala.util.matching.Regex.Match, чтобы получить дополнительную информацию о совпадении. Например:

import scala.util.matching.Regex
val datePattern = new Regex("""(\d\d\d\d)-(\d\d)-(\d\d)""", "year", "month", "day")
val text = "From 2011-07-15 to 2011-07-17"
val repl = datePattern replaceAllIn (text, m => s"${m group "month"}/${m group "day"}")

В строке замены знак доллара ($) за которым следует число будет интерпретироваться как ссылка на группу в шаблоне совпадения, числа от 1 до 9 соответствуют первым девяти группам, а 0 — всему совпадению. Любой другой символ является ошибкой. Символ обратной косой черты (\) будет интерпретироваться как символ экранирования и может использоваться для экранирования знака доллара. Для экранирования этих символов используйте Regex.quoteReplacement.

Параметры
replacer

Функция, которая отображает совпадение в другую строку.

target

Строка для поиска совпадений.

Возвращаемое значение

Строка target после замены.

Исходный код
def replaceFirstIn(target: CharSequence, replacement: String): String

Заменяет первое совпадение строкой.

В строке замены знак доллара ($) за которым следует число будет интерпретироваться как ссылка на группу в шаблоне совпадения, числа от 1 до 9 соответствуют первым девяти группам, а 0 — всему совпадению. Любой другой символ является ошибкой. Символ обратной косой черты (\) будет интерпретироваться как символ экранирования и может использоваться для экранирования знака доллара. Для экранирования этих символов используйте Regex.quoteReplacement.

Параметры
replacement

Строка, которая заменит совпадение.

target

Строка для поиска совпадений.

Возвращаемое значение

Результирующая строка.

Исходный код
def replaceSomeIn(target: CharSequence, replacer: Match => Option[String]): String

Заменяет некоторые совпадения с помощью функции замены, которая возвращает scala.Option. Функция замены принимает scala.util.matching.Regex.Match, чтобы получить дополнительную информацию о совпадении. Например:

import scala.util.matching.Regex._

val vars = Map("x" -> "a var", "y" -> """some $ and \ signs""")
val text = "A text with variables %x, %y and %z."
val varPattern = """%(\w+)""".r
val mapper = (m: Match) => vars get (m group 1) map (quoteReplacement(_))
val repl = varPattern replaceSomeIn (text, mapper)

В строке замены знак доллара ($) за которым следует число будет интерпретироваться как ссылка на группу в шаблоне совпадения, числа от 1 до 9 соответствуют первым девяти группам, а 0 — всему совпадению. Любой другой символ является ошибкой. Символ обратной косой черты (\) будет интерпретироваться как символ экранирования и может использоваться для экранирования знака доллара. Для экранирования этих символов используйте Regex.quoteReplacement.

Параметры
replacer

Функция, которая необязательно отображает совпадение в другую строку.

target

Строка для поиска совпадений.

Возвращаемое значение

Строка target после замены.

Исходный код
def split(toSplit: CharSequence): Array[String]

Разбивает заданную последовательность символов вокруг совпадений этого регулярного выражения.

Параметры
toSplit

Последовательность символов для разделения.

Возвращаемое значение

Массив строк, полученный путем разделения входных данных вокруг совпадений этого регулярного выражения.

Исходный код
override def toString: String

Строка, определяющая регулярное выражение.

Определение класса Any

Исходный код
def unanchored: UnanchoredRegex

Создайте новый Regex с тем же шаблоном, но без требования, что вся строка должна совпадать в шаблонах экстракторов и Regex#matches.

Обычно, сопоставление с date ведет себя так, как будто шаблон заключен в якоря, "^pattern$".

Без якорей Regex ведет себя так, как будто эти якоря были удалены.

Обратите внимание, что этот метод фактически не удаляет какие-либо соответствия из шаблона.

Вызов anchored возвращает исходный Regex.

val date = """(\d\d\d\d)-(\d\d)-(\d\d)""".r.unanchored

val date(year, month, day) = "Date 2011-07-15"                       // OK

val copyright: String = "Date of this document: 2011-07-15" match {
  case date(year, month, day) => s"Copyright $year"                  // OK
  case _                      => "No copyright"
}
Возвращает

Новый неявкоренный regex

Источник
def unapplySeq(s: CharSequence): Option[Список[Строка]]

Попытка сопоставления с java.lang.CharSequence.

Если сопоставление успешно, результатом является список соответствующих групп (или элемент null , если группа не совпала ни с каким вводом). Если шаблон не определяет групп, то результатом при успешном сопоставлении будет пустой список.

По умолчанию этот метод пытается сопоставить весь ввод; для поиска следующей совпадающей подпоследовательности используйте неявкоренный Regex.

Например:

val p1 = "ab*c".r
val p1Matches = "abbbc" match {
  case p1() => true               // no groups
  case _    => false
}
val p2 = "a(b*)c".r
val p2Matches = "abbbc" match {
  case p2(_*) => true             // any groups
  case _      => false
}
val numberOfB = "abbbc" match {
  case p2(b) => Some(b.length)    // one group
  case _     => None
}
val p3 = "b*".r.unanchored
val p3Matches = "abbbc" match {
  case p3() => true               // find the b's
  case _    => false
}
val p4 = "a(b*)(c+)".r
val p4Matches = "abbbcc" match {
  case p4(_*) => true             // multiple groups
  case _      => false
}
val allGroups = "abbbcc" match {
  case p4(all @ _*) => all mkString "/" // "bbb/cc"
  case _            => ""
}
val cGroup = "abbbcc" match {
  case p4(_, c) => c
  case _        => ""
}
Параметры значения
s

Строка для сопоставления

Возвращает

Совпадения

Источник
def unapplySeq(c: Символ): Option[Список[Символ]]

Попытка сопоставления с представлением строки scala.Char.

Если сопоставление успешно, результатом является первая совпадающая группа, если такие группы определены, или пустая последовательность в противном случае.

Например:

val cat = "cat"
// the case must consume the group to match
val r = """(\p{Lower})""".r
cat(0) match { case r(x) => true }
cat(0) match { case r(_) => true }
cat(0) match { case r(_*) => true }
cat(0) match { case r() => true }     // no match

// there is no group to extract
val r = """\p{Lower}""".r
cat(0) match { case r(x) => true }    // no match
cat(0) match { case r(_) => true }    // no match
cat(0) match { case r(_*) => true }   // matches
cat(0) match { case r() => true }     // matches

// even if there are multiple groups, only one is returned
val r = """((.))""".r
cat(0) match { case r(_) => true }    // matches
cat(0) match { case r(_,_) => true }  // no match
Параметры значения
c

Символ для сопоставления

Возвращает

Совпадение

Источник
def unapplySeq(m: Match): Option[Список[Строка]]

Попытка сопоставления с scala.util.matching.Regex.Match.

Ранее неудачное сопоставление приводит к None.

Если было сделано успешное сопоставление с текущим шаблоном, то используется этот результат.

В противном случае этот Regex применяется к ранее сопоставленному вводу, и используется результат этого сопоставления.

Конкретные поля

Источник
val pattern: Pattern

© 2002-2022 EPFL, with contributions from Lightbend.
Licensed under the Apache License, Version 2.0.
https://scala-lang.org/api/3.1.1/scala/util/matching/Regex.html

Spec-Zone.ru

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