Строки с кириллицей в Python: полное руководство для разработчика

Раздел: Работа со строками -> русский язык в строках

Основные подходы к работе с русскими строками

Базовое решение – встроенная поддержка Unicode в Python 3. Все строки (тип str) хранят символы в виде Unicode-кодовых точек. Русские буквы (кириллица) входят в Unicode, поэтому для обычных операций (конкатенация, поиск, замена, форматирование) дополнительных действий не требуется.

Пример прямого использования:

text = "Привет, мир!"
print(text[::-1])  # "!рим ,тевирП"
print(len(text))   # 12

текста русские python (работа с русским текстом в python)

При работе с внешними источниками (файлы, сеть, базы данных) необходимо согласовывать кодировку. Наиболее распространённая – UTF-8. Чтение файла с явным указанием кодировки:

with open('file.txt', 'r', encoding='utf-8') as f:
    content = f.read()

Запись:

with open('output.txt', 'w', encoding='utf-8') as f:
    f.write('Русский текст')

Типичная ошибка – опустить encoding при чтении файла, созданного в UTF-8. На Windows Python может использовать системную кодировку (например, cp1251) и получить UnicodeDecodeError. Решение – всегда явно задавать кодировку.

Проблема с консолью: вывод русских символов может отображаться кракозябрами. Настройка кодировки консоли в Windows через chcp 65001 или установка переменной окружения PYTHONIOENCODING=utf-8.

Как работать с русским текстом в кодировке CP1251 (Windows)?

Если документ сохранён в однобайтовой кодировке CP1251, при открытии указывается encoding='cp1251'. Аналогично для других кодировок (koi8-r, iso-8859-5).

with open('win_text.txt', 'r', encoding='cp1251') as f:
    text = f.read()
# Далее работа в Unicode
print(text)

Смешивание кодировок в одном проекте приводит к UnicodeDecodeError или появлению знаков вопроса. Необходимо определить кодировку источника (библиотека chardet) или принудительно преобразовывать байты.

Как корректно сравнивать русские строки без учёта регистра?

Простейший способ – привести обе строки к нижнему регистру через .lower(). Но метод .lower() корректно обрабатывает кириллицу, включая «Ё» (преобразует к «ё»). Для более сложных случаев (например, турецкая I) используется .casefold() – более агрессивное приведение, подходящее для регистронезависимого сравнения.

s1 = "Столица"
s2 = "столицА"
print(s1.lower() == s2.lower())  # True
print(s1.casefold() == s2.casefold())  # True

Буква «ё» в .lower() преобразуется в «ё», а «Ё» – тоже в «ё», поэтому сравнение «Ель» и «ёлка» после lower не покажет равенства. Если нужно считать «ё» и «е» одинаковыми, следует предварительно заменить одну на другую:

s1 = "еж"
s2 = "ёж"
normalized = lambda s: s.lower().replace('ё', 'е').replace('Ё', 'е').replace('е', 'е')
print(normalized(s1) == normalized(s2))  # True

Как использовать регулярные выражения для поиска русских слов?

Библиотека re поддерживает Unicode, если флаг re.UNICODE включён (по умолчанию в Python 3). Диапазон для кириллицы: [а-яё], [А-ЯЁ]. Для учёта регистра используется re.IGNORECASE.

import re
pattern = r'[а-яёА-ЯЁ]+'
text = "Москва – столица РФ."
words = re.findall(pattern, text)
print(words)  # ['Москва', 'столица', 'РФ']

Частая ошибка – написание [а-я] без буквы «ё». В стандартный диапазон «а-я» буква «ё» не входит, её нужно добавлять явно. Альтернатива – использовать символьный класс Unicode \p{Cyrillic} через модуль regex (сторонняя библиотека).

Как нормализовать русский текст: разные Unicode-представления буквы «ё»?

Буква «ё» может быть представлена как отдельный символ (U+0451) или как комбинация «е» (U+0435) с диакритическим знаком (U+0308). Модуль unicodedata позволяет привести к одной форме через normalize(). Форма NFC сворачивает составные символы, NFD разворачивает.

import unicodedata
text1 = "ё"  # e + диакритика (два символа)
text2 = "ё"   # один символ
print(unicodedata.normalize('NFC', text1) == unicodedata.normalize('NFC', text2))  # True

Поиск или сравнение строк, полученных из разных источников, может давать разные результаты из-за нормализации. Рекомендуется перед сравнением всегда приводить строки к одной нормализованной форме (чаще NFC).

Как работать с русскими именами файлов в Windows?

Современные версии Windows (NTFS) используют UTF-16, но Python для работы с путями использует кодировку, указанную в sys.getfilesystemencoding() (обычно utf-8 или mbcs). Для совместимости с русскими именами достаточно передавать пути как обычные Unicode-строки.

import os
filename = "документ.txt"
with open(filename, 'w', encoding='utf-8') as f:
    f.write('содержимое')
print(os.listdir('.'))  # список включает русские имена

Если имя файла получено извне и закодировано в cp1251, необходимо декодировать в Unicode: name = raw_bytes.decode('cp1251'). В обратную сторону при записи в файловую систему можно положиться на автоматическое кодирование через системную кодировку.

Расширенные примеры обработки русского текста

Автоматическое определение кодировки файла с русским текстом

Библиотека chardet (установка: pip install chardet) позволяет угадать кодировку по первым байтам. Пример чтения файла с неизвестной кодировкой:

Пример
import chardet

with open('unknown.txt', 'rb') as f:
    raw = f.read(10000)  # читаем начало файла
detected = chardet.detect(raw)
encoding = detected['encoding']
print(f"Определённая кодировка: {encoding}")  # например, utf-8 или windows-1251

with open('unknown.txt', 'r', encoding=encoding, errors='replace') as f:
    content = f.read()
print(content[:200])
Определённая кодировка: utf-8
Русский текст...

Ошибка UnicodeDecodeError при неверном определении. В таких случаях параметр errors='replace' заменяет нечитаемый символ на символ замены (обычно �), что позволяет продолжить обработку, но теряет часть данных.

Регистронезависимый поиск слов с учётом буквы «ё»

Для поиска всех вариантов слова, включая разное написание «ё», используется предварительная замена в шаблоне:

Пример
import re

text = "Ёжик под ёлкой. Ежик и елку не нашел."
# Заменим в тексте все е/ё на временный маркер, чтобы оба варианта находились
# Компактнее: пишем регулярное выражение [её] с флагом IGNORECASE
pattern = r'[её]жик'
matches = re.findall(pattern, text, re.IGNORECASE)
print(matches)  # ['Ёжик', 'ёжик', 'ежик']
['Ёжик', 'ёжик', 'ежик']

Лемматизация русских слов с помощью pymorphy2

Библиотека pymorphy2 (установка: pip install pymorphy2) приводит слово к нормальной форме:

Пример
import pymorphy2

morph = pymorphy2.MorphAnalyzer()
words = ['книги', 'книгой', 'книга']
for w in words:
    p = morph.parse(w)[0]
    print(f"{w} -> {p.normal_form}")
книги -> книга
книгой -> книга
книга -> книга

Удаление стоп-слов из русского текста

Библиотека nltk содержит список русских стоп-слов. Пример фильтрации:

Пример
from nltk.corpus import stopwords
import nltk
nltk.download('stopwords')

russian_stopwords = set(stopwords.words('russian'))
text = "В лесу родилась ёлочка, в лесу она росла."
words = text.lower().split()
filtered = [w for w in words if w.strip('.,!?') not in russian_stopwords]
print(filtered)
['лесу', 'родилась', 'ёлочка', 'лесу', 'росла']

Некорректное удаление из-за пунктуации: необходимо очищать слова от знаков препинания. Лучше использовать re.findall(r'[а-яё]+', text) для получения списка чистых слов.

Транслитерация русских символов в латиницу

Библиотека transliterate (установка: pip install transliterate) преобразует кириллицу в латиницу по стандарту ISO 9 или другим:

Пример
from transliterate import translit

text = "Привет, мир!"
result = translit(text, reversed=True)  # reversed=True – из кириллицы в латиницу
print(result)
Privet, mir!

Извлечение предложений, содержащих определённое русское слово

Пример с использованием регулярного выражения для разделения на предложения и фильтрации:

Пример
import re

text = "Москва – столица России. В ней живёт много людей. Столица является крупным городом."
sentences = re.split(r'(?<=[.!?])\s+', text)
keyword = "столица"
filtered = [s for s in sentences if keyword in s.lower()]
print(filtered)
['Москва – столица России.', 'Столица является крупным городом.']

Обработка русского текста в CSV-файлах

Модуль csv корректно работает с Unicode, если файл открыт с указанием кодировки UTF-8. Ошибки возникают при несовпадении кодировок в заголовке и данных:

Пример
import csv

data = [['Фамилия', 'Имя'], ['Иванов', 'Иван'], ['Сидорова', 'Мария']]
with open('people.csv', 'w', encoding='utf-8', newline='') as f:
    writer = csv.writer(f)
    writer.writerows(data)

with open('people.csv', 'r', encoding='utf-8') as f:
    reader = csv.reader(f)
    for row in reader:
        print(', '.join(row))
Фамилия, Имя
Иванов, Иван
Сидорова, Мария

Если CSV-файл сохранён в кодировке Windows-1251, при открытии с encoding='utf-8' возникнет UnicodeDecodeError. Решение: определить фактическую кодировку (например, через chardet) и указать её.

работа с русским текстом в Python - comments

En
текста русские python (python)