Spec-Zone.ru › Scala 3.2

Класс Regex.Regex

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

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"

Source
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

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

Source
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

Source
def matches(source: CharSequence): Boolean

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

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

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

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

Возвращает

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

См. также

Regex#unanchored

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

Source
def regex: String

Source
def replaceAllIn(target: CharSequence, replacement: String): String

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

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

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

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

target

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

Возвращает

Результат

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

Source
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 после замены.

Source
def replaceFirstIn(target: CharSequence, replacement: String): String

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

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

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

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

target

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

Возвращает

Результат

Source
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 после замены.

Source
def split(toSplit: CharSequence): Array[String]

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

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

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

Возвращает

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

Source
override def toString: String

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

Определяющие классы Any

Source
def unanchored: UnanchoredRegex

Создать новый Regex с тем же шаблоном, но без требования, чтобы весь String соответствовал шаблону в шаблонах извлекателей и 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

Source
def unapplySeq(s: CharSequence): Option[List[String]]

Попытка сопоставить 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

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

Возвращает

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

Source
def unapplySeq(c: Char): Option[List[Char]]

Попытка сопоставить строковое представление 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

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

Возвращает

Сопоставление

Source
def unapplySeq(m: Match): Option[List[String]]

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

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

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

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

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

Source
val pattern: Pattern

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

Spec-Zone.ru

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