Класс 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"
})
| Параметры значения |
|
|---|---|
| См. также | |
| Суператипы | |
| Известные подтипы | |
| Тип самого себя |
Конструкторы
Исходный код
Скомпилировать регулярное выражение, заданное в виде строки, в шаблон, который можно сопоставить с входными данными.
Если имена групп заданы, они могут быть использованы следующим образом:
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).
| Параметры значения |
|
|---|
Конкретные методы
Исходный код
Исходный код
Возвращает все неперекрывающиеся совпадения этого 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 для получения подробностей.
| Параметры значения |
|
|---|---|
| Возвращает | scala.util.matching.Regex.MatchIterator совпадающих подстрок. |
| Пример |
for (words <- """\w+""".r findAllIn "A simple example.") yield words |
Исходный код
Возвращает все неперекрывающиеся совпадения этого регулярного выражения в данной последовательности символов в виде scala.collection.Iterator объектов scala.util.matching.Regex.Match.
| Параметры значения |
|
|---|---|
| Возвращает | scala.collection.Iterator объектов scala.util.matching.Regex.Match для всех совпадений. |
| Пример |
for (words <- """\w+""".r findAllMatchIn "A simple example.") yield words.start |
Исходный код
Возвращает необязательную первую совпадающую строку этого Regex в заданной последовательности символов или None, если совпадения нет.
| Параметры значения |
|
|---|---|
| Возвращает | Объект scala.Option первой совпадающей строки в тексте. |
| Пример |
"""\w+""".r findFirstIn "A simple example." foreach println // prints "A" |
Source
Возвращает необязательное первое совпадение этого Regex в заданной последовательности символов или None, если оно не существует.
Если совпадение успешно, можно обратиться к scala.util.matching.Regex.Match для получения дополнительной информации.
| Параметры значения |
|
|---|---|
| Возвращает | Значение 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
Возвращает необязательное совпадение этого Regex в начале заданной последовательности символов или None, если оно не соответствует никакому префиксу последовательности символов.
В отличие от findFirstMatchIn, этот метод возвращает совпадение только в начале входных данных.
| Параметры значения |
|
|---|---|
| Возвращает | Значение scala.Option scala.util.matching.Regex.Match совпадающей строки. |
| Пример |
"""\w+""".r findPrefixMatchOf "A simple example." map (_.after) // returns Some(" simple example.")
|
Source
Возвращает необязательное совпадение этого Regex в начале заданной последовательности символов или None, если оно не соответствует никакому префиксу последовательности символов.
В отличие от findFirstIn, этот метод возвращает совпадение только в начале входных данных.
| Параметры значения |
|
|---|---|
| Возвращает | Значение scala.Option совпадающего префикса. |
| Пример |
"""\p{Lower}""".r findPrefixOf "A simple example." // returns None, since the text does not begin with a lowercase letter
|
Source
Возвращает, соответствует ли это Regex заданной последовательности символов.
Как и экстракт, этот метод учитывает закрепление.
| Параметры значения |
|
|---|---|
| Возвращает | true тогда и только тогда, когда |
| См. также | |
| Пример |
"""\d+""".r matches "123" // returns true |
Source
Source
Заменяет все совпадения строкой.
В строке замены знак доллара ($) , за которым следует число, будет интерпретирован как ссылка на группу в совпадающем шаблоне, причём числа от 1 до 9 соответствуют первым девяти группам, а 0 — всему совпадению. Любой другой символ является ошибкой. Символ обратной косой черты (\) будет интерпретирован как символ экранирования и может использоваться для экранирования знака доллара. Используйте Regex.quoteReplacement для экранирования этих символов.
| Параметры значения |
|
|---|---|
| Возвращает | Результат |
| Пример |
"""\d+""".r replaceAllIn ("July 15", "<NUMBER>") // returns "July <NUMBER>"
|
Source
Заменяет все совпадения с использованием функции замены. Функция замены принимает 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 для экранирования этих символов.
| Параметры значения |
|
|---|---|
| Возвращает | Строка target после замены. |
Source
Заменяет первое совпадение строкой.
В строке замены знак доллара ($) , за которым следует число, будет интерпретирован как ссылка на группу в совпадающем шаблоне, причём числа от 1 до 9 соответствуют первым девяти группам, а 0 — всему совпадению. Любой другой символ является ошибкой. Символ обратной косой черты (\) будет интерпретирован как символ экранирования и может использоваться для экранирования знака доллара. Используйте Regex.quoteReplacement для экранирования этих символов.
| Параметры значения |
|
|---|---|
| Возвращает | Результат |
Source
Заменяет некоторые совпадения с помощью функции замены, которая возвращает 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 для экранирования этих символов.
| Параметры значения |
|
|---|---|
| Возвращает | Строка target после замены. |
Source
Разделяет предоставленную последовательность символов вокруг совпадений с этим регулярным выражением.
| Параметры значения |
|
|---|---|
| Возвращает | Массив строк, вычисленный путём разделения ввода вокруг совпадений с этим регулярным выражением |
Source
Строка, определяющая регулярное выражение
| Определяющие классы | Any |
|---|
Source
Создать новый 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
Попытка сопоставить 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 _ => ""
}
| Параметры значения |
|
|---|---|
| Возвращает | Сопоставления |
Source
Попытка сопоставить строковое представление 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
| Параметры значения |
|
|---|---|
| Возвращает | Сопоставление |
Source
Попытка сопоставления с scala.util.matching.Regex.Match.
Ранее неудачное сопоставление приводит к None.
Если было выполнено успешное сопоставление с текущим шаблоном, используется этот результат.
В противном случае этот Regex применяется к ранее сопоставленному вводу, и используется результат этого сопоставления.
Конкретные поля
Source
© 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