«1. Обзор
В этой статье мы рассмотрим возможности языка Groovy для сопоставления с образцом в строках.
Мы увидим, как подход Groovy с включенными батареями предоставляет нам мощный и эргономичный синтаксис для наших основных потребностей сопоставления с образцом.
2. Оператор шаблона
В языке Groovy представлен так называемый оператор шаблона ~. Этот оператор можно рассматривать как синтаксический сахарный ярлык для метода Java java.util.regex.Pattern.compile(string).
Давайте проверим это на практике в рамках теста Спока:
def "pattern operator example"() {
given: "a pattern"
def p = ~'foo'
expect:
p instanceof Pattern
and: "you can use slashy strings to avoid escaping of blackslash"
def digitPattern = ~/\d*/
digitPattern.matcher('4711').matches()
}
Это тоже довольно удобно, но мы увидим, что этот оператор является просто базовым для некоторых других, еще более полезных операторов.
3. Оператор сопоставления
Большую часть времени, и особенно при написании тестов, мы на самом деле не заинтересованы в создании объектов Pattern, а вместо этого хотим проверить, соответствует ли String определенному регулярному выражению (или Pattern) . Таким образом, Groovy также содержит оператор сопоставления ==~.
Возвращает логическое значение и выполняет строгое соответствие заданному регулярному выражению. По сути, это синтаксический ярлык для вызова Pattern.matches(regex, string).
Опять же, мы рассмотрим это на практике в рамках теста Спока:
def "match operator example"() {
expect:
'foobar' ==~ /.*oba.*/
and: "matching is strict"
!('foobar' ==~ /foo/)
}
4. Оператор поиска
Последним оператором Groovy в контексте сопоставления с образцом является оператор поиска ~=. В этом случае оператор будет напрямую создавать и возвращать экземпляр java.util.regex.Matcher.
Конечно, мы можем воздействовать на этот экземпляр Matcher, обращаясь к его известным методам Java API. Но, кроме того, мы также можем получить доступ к соответствующим группам, используя многомерный массив.
И это еще не все — экземпляр Matcher автоматически приведет к логическому типу, вызвав свой метод find(), если он используется в качестве предиката. Цитируя официальную документацию Groovy, это означает, что «оператор =~ совместим с простым использованием оператора Perl =~».
Здесь мы видим оператор в действии:
def "find operator example"() {
when: "using the find operator"
def matcher = 'foo and bar, baz and buz' =~ /(\w+) and (\w+)/
then: "will find groups"
matcher.size() == 2
and: "can access groups using array"
matcher[0][0] == 'foo and bar'
matcher[1][2] == 'buz'
and: "you can use it as a predicate"
'foobarbaz' =~ /bar/
}
5. Заключение
Мы увидели, как язык Groovy очень удобно предоставляет нам доступ к встроенным функциям Java, касающимся регулярных выражений. .
Официальная документация Groovy также содержит несколько кратких примеров по этой теме. Это особенно здорово, если учесть, что примеры кода в документации выполняются как часть сборки документации.
Как всегда, примеры кода можно найти на GitHub.