«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.