Пакет strings: продвинутые операции со строками


1. Проблема ручного парсинга

Задача: разбить CSV-строку на слова

csv := "apple;banana;cherry;date"

Цель: Получить каждое слово отдельно.


Ручное решение (сложно)

csv := "apple;banana;cherry;date"
words := []string{}
currentWord := ""

for _, char := range csv {
    if char == ';' {
        words = append(words, currentWord)
        currentWord = ""  // Обнуляем буфер
        continue
    }
    currentWord += string(char)
}

// Не забыть последнее слово
words = append(words, currentWord)

fmt.Println(words)  // [apple banana cherry date]

Проблема: Много кода для простой задачи.


2. Решение через strings.Split

csv := "apple;banana;cherry;date"
words := strings.Split(csv, ";")

fmt.Println(words)  // [apple banana cherry date]

Одна строка вместо цикла!


Особенность: пустая строка в конце

csv := "apple;banana;cherry;"  // Точка с запятой в конце

words := strings.Split(csv, ";")
fmt.Println(words)  // [apple banana cherry ""]

Последний элемент — пустая строка.


3. Основные функции strings

Категория Функции
Поиск Contains, Index, LastIndex, Count
Проверка HasPrefix, HasSuffix
Замена Replace, ReplaceAll
Разделение Split, Fields, Join
Регистр ToLower, ToUpper
Очистка TrimSpace, Trim, TrimLeft, TrimRight
Повторение Repeat

4. Сравнение строк

Лексикографическое сравнение

s1 := "apple"
s2 := "banana"
s3 := "apple"

fmt.Println(s1 == s3)  // true
fmt.Println(s1 == s2)  // false
fmt.Println(s1 < s2)   // true (лексикографически)

Сравнение по Unicode кодам символов.


Механизм сравнения

"мама" vs "маша"

Шаг 1: 'м' == 'м' → продолжить
Шаг 2: 'а' == 'а' → продолжить
Шаг 3: 'м' vs 'ш'
       код('м') < код('ш') → "мама" < "маша"

Сравнение идёт по рунам, пока не найдётся различие.


Регистр имеет значение

s1 := "Hello"
s2 := "hello"

fmt.Println(s1 == s2)  // false — регистр учитывается

Заглавные буквы имеют другие коды:

fmt.Println('H')  // 72
fmt.Println('h')  // 104

Поэтому 'H' < 'h'.


Визуальная похожесть ≠ равенство

s1 := "М"  // Кириллица
s2 := "M"  // Латиница

fmt.Println(s1 == s2)  // false
fmt.Printf("'М' (кириллица) = %d\n", 'М')  // 1052
fmt.Printf("'M' (латиница) = %d\n", 'M')   // 77

Выглядят одинаково, но коды разные!


5. Сравнение без учёта регистра

hello1 := "Hello"
hello2 := "hello"

fmt.Println(hello1 == hello2)  // false

// ✅ Без учёта регистра
fmt.Println(strings.EqualFold(hello1, hello2))  // true

strings.EqualFold() — case-insensitive сравнение.


6. Поиск подстрок

Contains — проверка наличия

text := "Go is awesome! Go is fast!"

fmt.Println(strings.Contains(text, "awesome"))  // true
fmt.Println(strings.Contains(text, "python"))   // false

Index — первое вхождение

fmt.Println(strings.Index(text, "Go"))   // 0
fmt.Println(strings.Index(text, "is"))   // 3
fmt.Println(strings.Index(text, "xyz"))  // -1 (не найдено)

Возвращает индекс или -1.


LastIndex — последнее вхождение

fmt.Println(strings.LastIndex(text, "Go"))  // 15

Count — количество вхождений

fmt.Println(strings.Count(text, "Go"))  // 2

7. Префикс и суффикс

url := "https://golang.org"

fmt.Println(strings.HasPrefix(url, "https"))  // true
fmt.Println(strings.HasSuffix(url, ".org"))   // true

Применение: Проверка расширений файлов, протоколов.


8. Замена подстрок

Replace — ограниченная замена

original := "I love Python. Python is great!"

// Заменить первое вхождение
replaced := strings.Replace(original, "Python", "Go", 1)
fmt.Println(replaced)  // "I love Go. Python is great!"

n=1 — заменить только первое вхождение.


ReplaceAll — замена всех вхождений

replacedAll := strings.ReplaceAll(original, "Python", "Go")
fmt.Println(replacedAll)  // "I love Go. Go is great!"

9. Разделение строк

Split — по разделителю

csv := "apple;banana;cherry;date"
parts := strings.Split(csv, ";")

fmt.Println(parts)  // [apple banana cherry date]
fmt.Println(len(parts))  // 4

Fields — по пробелам

sentence := "Go is   awesome"
words := strings.Fields(sentence)

fmt.Println(words)  // [Go is awesome]

Игнорирует множественные пробелы.


10. Объединение строк

fruits := []string{"apple", "banana", "cherry"}
joined := strings.Join(fruits, ", ")

fmt.Println(joined)  // "apple, banana, cherry"

Join — эффективнее, чем + в цикле.


11. Удаление пробелов

TrimSpace — края строки

messy := "   Hello, World!   "
trimmed := strings.TrimSpace(messy)

fmt.Printf("До: \"%s\" (len=%d)\n", messy, len(messy))     // 20
fmt.Printf("После: \"%s\" (len=%d)\n", trimmed, len(trimmed))  // 13

Trim, TrimLeft, TrimRight

dashes := "---Hello---"

fmt.Println(strings.Trim(dashes, "-"))       // "Hello"
fmt.Println(strings.TrimLeft(dashes, "-"))   // "Hello---"
fmt.Println(strings.TrimRight(dashes, "-"))  // "---Hello"

Удаляет указанные символы.


12. Изменение регистра

mixed := "Hello, World!"

fmt.Println(strings.ToLower(mixed))  // "hello, world!"
fmt.Println(strings.ToUpper(mixed))  // "HELLO, WORLD!"

С unicode для рун

r := 'Ж'

fmt.Println(unicode.IsUpper(r))     // true
fmt.Println(unicode.ToLower(r))     // 'ж'

13. Повторение строк

pattern := "Go"
repeated := strings.Repeat(pattern, 5)

fmt.Println(repeated)  // "GoGoGoGoGo"

14. Проверка типа символов (unicode)

testChars := []rune{'A', 'б', '5', ' ', '!'}

for _, ch := range testChars {
    fmt.Printf("'%c': ", ch)
    fmt.Printf("буква=%t, ", unicode.IsLetter(ch))
    fmt.Printf("цифра=%t, ", unicode.IsDigit(ch))
    fmt.Printf("пробел=%t, ", unicode.IsSpace(ch))
    fmt.Printf("пунктуация=%t\n", unicode.IsPunct(ch))
}

Вывод:

'A': буква=true, цифра=false, пробел=false, пунктуация=false
'б': буква=true, цифра=false, пробел=false, пунктуация=false
'5': буква=false, цифра=true, пробел=false, пунктуация=false
' ': буква=false, цифра=false, пробел=true, пунктуация=false
'!': буква=false, цифра=false, пробел=false, пунктуация=true

15. Итоги

strings.Split — разделение строки в одну строку кода
Сравнение строк — лексикографически, по кодам рун
strings.EqualFold — сравнение без учёта регистра
✅ Визуально похожие символы (кириллица/латиница) не равны
✅ Богатый набор функций: поиск, замена, разделение, очистка
strings.Fields — автоматически убирает множественные пробелы
strings.Join — эффективное объединение
unicode — проверка типа символов

Ключевое правило:

Перед реализацией вручную → проверьте пакет strings
Вероятность: функция уже существует ≈ 90%

Практический паттерн:

// ❌ Сложно вручную
for _, char := range csv {
    // много кода...
}

// ✅ Одна строка
words := strings.Split(csv, ";")

Замечание:
Позже будет пакет strings, который сэкономит часы разработки.