Go: проверка вхождения подстроки в строку — полное руководство

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

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

Начать курс

Как в Go проверить, содержит ли строка подстроку? От новичка до профи

Вы когда-нибудь писали на Go и вдруг замирали перед простым вопросом: «А содержит ли эта строка нужную мне часть?» Если да — вы не одиноки. На Stack Overflow этот вопрос набрал тысячи просмотров, и не зря. В Go есть несколько элегантных способов решить эту задачу, но какой выбрать? Давайте разберемся раз и навсегда.

В этой статье мы не просто покажем вам функцию strings.Contains. Мы научим вас думать как Go-разработчик: выбирать оптимальный инструмент для каждой ситуации, избегать подводных камней и писать код, который будет работать быстро и предсказуемо.

Содержание

1. strings.Contains — ваш первый друг

Начнем с самого простого и популярного способа. Функция strings.Contains из стандартной библиотеки Go — это то, что вам нужно в 80% случаев. Она возвращает true, если строка содержит указанную подстроку, и false в противном случае.

Вот как это выглядит в реальном коде:

package main

import (
    "fmt"
    "strings"
)

func main() {
    str := "Привет, мир Go!"
    substr := "мир"

    if strings.Contains(str, substr) {
        fmt.Println("Строка содержит подстроку:", substr)
    } else {
        fmt.Println("Подстрока не найдена")
    }
}

Вывод:

Строка содержит подстроку: мир

Просто, правда? Функция чувствительна к регистру: strings.Contains("Go", "go") вернет false. Если вам нужно игнорировать регистр, придется использовать strings.ToLower или strings.EqualFold.

Пример с игнорированием регистра

str := "Golang is awesome"
substr := "golang"

if strings.Contains(strings.ToLower(str), strings.ToLower(substr)) {
    fmt.Println("Найдено (без учета регистра)!")
}

Когда использовать: когда вам нужен простой бинарный ответ — «есть» или «нет». Без лишних деталей.

2. strings.Index — когда нужно знать позицию

Иногда мало знать, что подстрока есть. Хочется понять, где именно она находится. Например, вы парсите лог и хотите вырезать часть строки после определенного маркера. Тут на помощь приходит strings.Index.

Эта функция возвращает индекс первого вхождения подстроки (начиная с 0) или -1, если подстрока не найдена.

str := "Ошибка: файл не найден в /var/log"
substr := "файл"

pos := strings.Index(str, substr)
if pos != -1 {
    fmt.Printf("Подстрока найдена на позиции %d\n", pos)
    fmt.Printf("Контекст: %s\n", str[pos:])
} else {
    fmt.Println("Подстрока не найдена")
}

Вывод:

Подстрока найдена на позиции 7
Контекст: файл не найден в /var/log

Есть и другие вариации:

  • strings.LastIndex — ищет последнее вхождение
  • strings.IndexAny — ищет первое вхождение любого символа из набора
  • strings.IndexRune — ищет конкретный Unicode-символ
// Пример с LastIndex
str := "a-b-c-d"
lastDash := strings.LastIndex(str, "-")
fmt.Println("Последнее тире на позиции:", lastDash) // 5

// Пример с IndexAny
str2 := "hello world"
pos := strings.IndexAny(str2, "aeiou")
fmt.Println("Первая гласная на позиции:", pos) // 1 (буква 'e')

Когда использовать: когда вам нужно не только проверить наличие, но и получить позицию для дальнейшей обработки.

3. ContainsAny и ContainsRune — тонкая настройка

Go предлагает еще несколько полезных функций для специфических случаев.

strings.ContainsAny

Проверяет, содержит ли строка любой из перечисленных символов. Обратите внимание: это не подстроки, а отдельные символы (руны).

str := "Gopher!"
hasVowel := strings.ContainsAny(str, "aeiouy")
fmt.Println("Содержит гласную?", hasVowel) // true

hasDigit := strings.ContainsAny(str, "0123456789")
fmt.Println("Содержит цифру?", hasDigit) // false

strings.ContainsRune

Проверяет наличие конкретного Unicode-символа (руны). Это эффективнее, чем искать односимвольную строку.

str := "Привет, мир!"
runeToFind := 'м'

if strings.ContainsRune(str, runeToFind) {
    fmt.Println("Руна найдена!")
}

Когда использовать: ContainsAny — для быстрой проверки на наличие любого символа из набора (например, валидация пароля). ContainsRune — когда работаете с Unicode и знаете точный символ.

4. Производительность: что выбрать?

Go славится своей производительностью, и строковые операции здесь не исключение. Но разные функции имеют разную сложность. Давайте сравним:

Функция Сложность Лучший сценарий
strings.Contains O(n + m) Простая проверка на вхождение
strings.Index O(n + m) Нужна позиция подстроки
strings.ContainsAny O(n * k) Проверка на любой символ из набора
strings.ContainsRune O(n) Поиск одного символа

Примечание: n — длина строки, m — длина подстроки, k — количество символов в наборе.

На практике для большинства задач разница незаметна. Но если вы обрабатываете миллионы строк или работаете с очень длинными текстами (логи, ген

Блоги

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