Регулярные выражения в Go с примерами: полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Регулярные выражения в Go: мощный инструмент для работы с текстом

Регулярные выражения (regex) — незаменимый инструмент для поиска, извлечения и замены текста по шаблону. В языке Go (Golang) работа с регулярными выражениями реализована через стандартный пакет regexp. Он предоставляет быстрый и безопасный способ работы с шаблонами, используя синтаксис, близкий к Perl и RE2. В этой статье мы разберём основные функции пакета на практических примерах.

1. Основы работы с пакетом regexp

Пакет regexp следует принципу «компилируй один раз, используй много раз». Это повышает производительность при многократном применении одного шаблона. Основные функции:

  • regexp.Compile(expr) — компилирует регулярное выражение. Возвращает *Regexp и ошибку.
  • regexp.MustCompile(expr) — то же самое, но вызывает панику при ошибке. Удобно для инициализации глобальных переменных.
  • regexp.MatchString(expr, s) — проверяет, содержит ли строка s хотя бы одно совпадение с шаблоном.
package main

import (
    "fmt"
    "regexp"
)

func main() {
    // Простая проверка: содержит ли строка цифры?
    matched, _ := regexp.MatchString(`\d+`, "Заказ №12345")
    fmt.Println(matched) // true

    // Компилируем шаблон для многократного использования
    re := regexp.MustCompile(`[a-z]+`)
    fmt.Println(re.MatchString("hello")) // true
    fmt.Println(re.MatchString("HELLO")) // false
}

Обратите внимание: по умолчанию MatchString ищет частичное совпадение (как strings.Contains). Для полного совпадения строки с шаблоном используйте якоря ^ и $.

2. Поиск и извлечение данных

Для поиска всех совпадений или первого вхождения используйте методы FindString, FindAllString, FindStringSubmatch и их аналоги для срезов байтов.

2.1. Поиск первого совпадения

re := regexp.MustCompile(`\b\w+@\w+\.\w+\b`)
email := re.FindString("Свяжитесь с нами: support@example.com или info@test.org")
fmt.Println(email) // support@example.com

2.2. Поиск всех совпадений

re := regexp.MustCompile(`\d{4}`)
numbers := re.FindAllString("Коды: 1234, 5678, 9012", -1)
fmt.Println(numbers) // [1234 5678 9012]

Второй аргумент FindAllString — максимальное количество совпадений. -1 означает «все».

2.3. Группы захвата (submatch)

Группы захвата позволяют извлечь части совпадения. Они задаются круглыми скобками ().

re := regexp.MustCompile(`(\w+)@(\w+\.\w+)`)
match := re.FindStringSubmatch("user@example.com")
fmt.Println(match) // [user@example.com user example.com]
// match[0] — полное совпадение
// match[1] — первая группа (user)
// match[2] — вторая группа (example.com)

3. Замена текста с помощью регулярных выражений

Пакет regexp предоставляет два основных метода для замены:

  • ReplaceAllString(src, repl) — заменяет все совпадения на строку repl.
  • ReplaceAllStringFunc(src, replFunc) — заменяет каждое совпадение, используя функцию обратного вызова.

3.1. Простая замена

re := regexp.MustCompile(`\s+`)
result := re.ReplaceAllString("Много   пробелов   здесь", " ")
fmt.Println(result) // "Много пробелов здесь"

3.2. Замена с использованием групп захвата

В строке замены можно ссылаться на группы через $1, $2 и т.д.

re := regexp.MustCompile(`(\w+)\s+(\w+)`)
result := re.ReplaceAllString("Иван Петров", "$2, $1")
fmt.Println(result) // "Петров, Иван"

3.3. Замена с функцией

re := regexp.MustCompile(`\d+`)
result := re.ReplaceAllStringFunc("Цена: 100 рублей", func(s string) string {
    // Увеличиваем каждое число на 10
    num, _ := strconv.Atoi(s)
    return strconv.Itoa(num + 10)
})
fmt.Println(result) // "Цена: 110 рублей"

4. Флаги и расширенные возможности

В Go нет встроенного синтаксиса флагов (как /i в Perl). Вместо этого флаги задаются в начале шаблона с помощью специальных конструкций:

  • (?i) — регистронезависимый режим.
  • (?m) — многострочный режим (якоря ^ и $ работают для каждой строки).
  • (?s) — режим, при котором . совпадает с любым символом, включая перевод строки.

4.1. Регистронезависимый поиск

re := regexp.MustCompile(`(?i)go`)
fmt.Println(re.FindString("Go is great")) // "Go"
fmt.Println(re.FindString("I love GO"))   // "GO"

4.2. Многострочный режим

text := `строка1
строка2
строка3`
// Без флага ^ ищет только в начале всей строки
re1 := regexp.MustCompile(`^строка`)
fmt.Println(re1.FindAllString(text, -1)) // [строка]

// С флагом (?m) ^ работает для каждой строки
re2 := regexp.MustCompile(`(?m)^строка`)
fmt.Println(re2.FindAllString(text, -1)) //                

Блоги

Рекомендаций по книгам