Срезы и поиск подстрок

Срезы и поиск подстрок

В модуле 1 вы познакомились со строками, а в модуле 2 разобрали базовые операции: конкатенацию, повторение и срезы. Теперь, имея за плечами циклы и коллекции, можно рассмотреть строки как последовательности глубже — с полноценным набором инструментов для поиска и извлечения подстрок.

Строка как последовательность

Строка — это неизменяемая последовательность символов. Всё, что применимо к спискам (индексы, срезы, in, len, for), работает и со строками:

s = "Hello, Python!"
print(len(s))      # 14
print(s[0])        # H
print(s[-1])       # !
print(s[7:13])     # Python
print(s[:5])       # Hello
print(s[::-1])     # !nohtyP ,olleH

Расширенные срезы

Напомним синтаксис: s[start:stop:step]. Все три параметра необязательны:

s = "abcdefghij"

print(s[::2])     # acegi — каждый второй
print(s[1::2])    # bdfhj — нечётные позиции
print(s[2:8])     # cdefgh
print(s[2:8:2])   # ceg — каждый второй из подстроки
print(s[-3:])     # hij — последние 3
print(s[:-3])     # abcdefg — все, кроме последних 3

Поиск подстроки: in и not in

Оператор in проверяет вхождение подстроки (регистрозависимо):

text = "Python is awesome"

print("Python" in text)   # True
print("python" in text)   # False — регистр важен!
print("is" in text)       # True
print("Java" not in text) # True

Метод find()

find(sub) возвращает индекс первого вхождения подстроки, или -1 если не найдено:

s = "Hello, World!"

print(s.find("World"))   # 7
print(s.find("o"))       # 4 (первая 'o')
print(s.find("xyz"))     # -1

# С указанием диапазона поиска:
print(s.find("o", 5))    # 8 — искать с позиции 5
print(s.find("o", 5, 12)) # 8 — искать в диапазоне [5, 12)

Метод rfind()

rfind(sub) — то же, но ищет с конца (последнее вхождение):

s = "Hello, World! Hello!"

print(s.find("Hello"))    # 0 — первое
print(s.rfind("Hello"))   # 14 — последнее

Метод index() и rindex()

Аналог find(), но выбрасывает ValueError вместо -1:

s = "Hello, Python!"

print(s.index("Python"))   # 7
# s.index("Java")           # ValueError: substring not found

Когда использовать find, а когда index? Если отсутствие подстроки — нормальный случай (нет данных) — используйте find и проверяйте на -1. Если отсутствие — ошибка в логике — index явнее выражает ожидание.

Подсчёт вхождений: count()

count(sub) считает, сколько раз подстрока встречается в строке:

s = "Mississippi"

print(s.count("s"))    # 4
print(s.count("ss"))   # 2
print(s.count("i"))    # 4
print(s.count("xyz"))  # 0

Вхождения не перекрываются: "aaa".count("aa")1.

Проверка начала и конца: startswith, endswith

filename = "report_2025.pdf"

print(filename.startswith("report"))   # True
print(filename.endswith(".pdf"))       # True
print(filename.endswith(".docx"))      # False

url = "https://example.com"
print(url.startswith("https"))         # True

Можно передать кортеж вариантов:

print(filename.endswith((".pdf", ".docx", ".xlsx")))   # True

Многострочный поиск

При работе с многострочными строками (тройные кавычки или \n) строки обрабатываются как единое целое:

poem = "Белеет парус одинокий\nВ тумане моря голубом"

print("туман" in poem)             # False
print("тумане" in poem)            # True
print(poem.find("\n"))             # 22 — позиция переноса
lines = poem.split("\n")           # разбить на строки (split в уроке 7-2)
print(len(lines))                  # 2

Практический пример: валидация e-mail

def is_valid_email(email):
    has_at = "@" in email
    at_pos = email.find("@")
    has_dot_after_at = "." in email[at_pos + 1:] if at_pos > 0 else False
    not_starts_with_at = not email.startswith("@")
    return has_at and has_dot_after_at and not_starts_with_at

print(is_valid_email("alice@example.com"))   # True
print(is_valid_email("alice@"))              # False
print(is_valid_email("@example.com"))        # False

Проверь себя

Что вернёт s.find("is") для строки s = "This is Python"?

"is" впервые встречается в "This" на позиции 2 (T-h-i-s). Ответ: 2.

Итог

  • Строка — неизменяемая последовательность; поддерживает индексы, срезы, in, for, len.
  • find(sub) → индекс первого вхождения или -1; rfind(sub) — последнего.
  • index(sub) → как find, но ValueError при отсутствии.
  • count(sub) → количество вхождений.
  • startswith(prefix), endswith(suffix) → проверка начала/конца строки.
  • Все методы работают с обычными строками и не изменяют исходную строку.

В следующем уроке разберём ключевые методы строк: split, join, strip, replace.

Попробуйте интерактивную версию

Практические задачи, квизы и AI-наставник — бесплатный старт без карты

Перейти к практике