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