Поиск строки в файле в Python от простого до продвинутого

Раздел: Python -> Файловый ввод-вывод

Поиск строки в файле: основные подходы

Как найти строку, содержащую заданную подстроку, наиболее эффективно?

Самым простым и эффективным способом поиска строки в файле на Python является построчное чтение файла с проверкой вхождения подстроки с помощью оператора in. Этот метод работает за линейное время O(N), где N - количество строк, и не требует загрузки всего файла в память, что важно для больших объемов данных.


with open('sample.txt', 'r', encoding='utf-8') as f:
    for line in f:
        if 'python' in line:
            print(line.rstrip('\n'))

ввод программ на python (ввод данных в программе python)

Пояснение: файл открывается с явным указанием кодировки (часто UTF-8), что предотвращает ошибки при чтении. Цикл for line in f читает файл построчно, не загружая его целиком. Оператор in проверяет, присутствует ли подстрока 'python' в текущей строке. Метод rstrip('\n') удаляет символ новой строки перед выводом, чтобы избежать лишних пустых строк в выводе.

Типичная проблема: UnicodeDecodeError возникает, если файл содержит символы, не соответствующие указанной кодировке. Решение - указать правильную кодировку или использовать параметр errors='ignore'.

Еще одна ошибка: забыть удалить символ новой строки при сравнении с точной строкой. Например, если ищем строку 'python\n' (с переводом строки), то оператор in будет работать некорректно. Рекомендуется всегда вызывать rstrip() для сравниваемой строки.

Как найти строку по регулярному выражению?

Если условие поиска сложнее, чем просто вхождение подстроки, на помощь приходит модуль re. Например, поиск строк, содержащих слово из трёх букв или цифры. Функция re.search() проверяет строку на соответствие шаблону.


import re

pattern = r'\b\w{3}\b'  # слова из ровно трёх букв
with open('sample.txt', 'r', encoding='utf-8') as f:
    for line in f:
        if re.search(pattern, line):
            print(line.rstrip())

Python file io (ввод-вывод файлов в python)

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

Для этого можно преобразовать строку к нижнему регистру перед проверкой. Либо использовать флаг re.IGNORECASE при работе с регулярными выражениями.


with open('sample.txt', 'r', encoding='utf-8') as f:
    for line in f:
        if 'python' in line.lower():
            print(line.rstrip())

Python temp files (временные файлы в python)

Как получить номера строк, где найдено совпадение?

Для этого используется функция enumerate() во время итерации.


with open('sample.txt', 'r', encoding='utf-8') as f:
    for num, line in enumerate(f, start=1):
        if 'python' in line:
            print(f'Строка {num}: {line.rstrip()}')

Python index files (индексация файлов в python)

Как найти все вхождения подстроки в файле?

Если требуется не только строка целиком, а все позиции, то можно использовать re.finditer() для каждой строки, либо собрать строки в список, если файл небольшой.


import re

with open('sample.txt', 'r', encoding='utf-8') as f:
    text = f.read()
    for match in re.finditer(r'python', text, re.IGNORECASE):
        print(f'Найдено на позиции {match.start()}: {match.group()}')

File python class (класс для работы с файлами в python)

Осторожно: этот метод загружает весь файл в память, что неприемлемо для очень больших файлов.

Как найти строки, содержащие одно из нескольких слов?

Можно использовать оператор any() со списком подстрок.


keywords = ['Python', 'Java', 'JavaScript']
with open('sample.txt', 'r', encoding='utf-8') as f:
    for line in f:
        if any(kw.lower() in line.lower() for kw in keywords):
            print(line.rstrip())

Python file utf 8 (кодировка utf-8 для файлов в python)

Проблема: при большом количестве ключевых слов или строк производительность может упасть. Решение - предварительно скомпилировать регулярное выражение с объединением слов через |.


import re
pattern = re.compile('|'.join(map(re.escape, keywords)), re.IGNORECASE)
with open('sample.txt', 'r', encoding='utf-8') as f:
    for line in f:
        if pattern.search(line):
            print(line.rstrip())

Python config files (конфигурационные файлы в python)

Как отфильтровать строки по нескольким условиям?

Например, найти строки, которые содержат 'error' и не являются комментариями.


with open('log.txt', 'r', encoding='utf-8') as f:
    for line in f:
        if 'error' in line.lower() and not line.strip().startswith('#'):
            print(line.rstrip())
- Python file methods (методы работы с файлами в python)
- File models in python (модели файлов в python)
- File handle python (обработка файлов в python)

Расширенные примеры поиска строки в файле

Пример 1: Поиск с контекстом (строки до и после)

Пример

from collections import deque

def search_with_context(filename, pattern, context=2):
    with open(filename, 'r', encoding='utf-8') as f:
        prev_lines = deque(maxlen=context)
        for line in f:
            if pattern in line:
                for i, ctx_line in enumerate(prev_lines, -context):
                    print(f'Контекст {i}: {ctx_line.rstrip()}')
                print(f'Найдено: {line.rstrip()}')
                # вывести следующие context строк
                next_lines = [next(f, '').rstrip() for _ in range(context)]
                for j, n_line in enumerate(next_lines, 1):
                    if n_line:
                        print(f'Контекст +{j}: {n_line}')
                break
            prev_lines.append(line)

search_with_context('sample.txt', 'python')
Контекст -2: Строка перед перед
Контекст -1: Строка перед
Найдено: эта строка содержит python
Контекст +1: следующая строка
Контекст +2: еще одна после

Пример 2: Запись найденных строк в другой файл

Пример

with open('input.txt', 'r', encoding='utf-8') as fin, \
     open('output.txt', 'w', encoding='utf-8') as fout:
    for line in fin:
        if 'error' in line.lower():
            fout.write(line)

После выполнения файл output.txt будет содержать только строки с ошибкой.

Пример 3: Использование mmap для больших файлов

Пример

import mmap

with open('huge.txt', 'rb') as f:
    mm = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
    index = mm.find(b'python')
    while index != -1:
        # извлечь строку (до ближайшего перевода строки)
        start = mm.rfind(b'\n', 0, index) + 1
        end = mm.find(b'\n', index)
        line = mm[start:end].decode('utf-8')
        print(f'Позиция {index}: {line}')
        index = mm.find(b'python', end)
    mm.close()
Позиция 1234: эта строка содержит python
Позиция 5678: еще один python

Пример 4: Подсчёт количества вхождений слов

Пример

from collections import Counter

with open('sample.txt', 'r', encoding='utf-8') as f:
    word_counts = Counter()
    for line in f:
        words = line.split()
        word_counts.update(words)
    print('Топ-5 самых частых слов:')
    for word, count in word_counts.most_common(5):
        print(f'{word}: {count}')
Топ-5 самых частых слов:
python: 15
java: 10
the: 8
a: 7
and: 6

Пример 5: Параллельный поиск с разбиением файла на части

Пример

import concurrent.futures
import os

def search_in_chunk(filename, chunk_start, chunk_size, pattern):
    with open(filename, 'r', encoding='utf-8') as f:
        f.seek(chunk_start)
        chunk = f.read(chunk_size)
        lines = chunk.split('\n')
        results = []
        for i, line in enumerate(lines, start=1):
            if pattern in line:
                results.append((chunk_start + i, line))
        return results

file_size = os.path.getsize('large.txt')
chunk_size = file_size // 4
futures = []
with concurrent.futures.ThreadPoolExecutor() as executor:
    for i in range(4):
        start = i * chunk_size
        future = executor.submit(search_in_chunk, 'large.txt', start, chunk_size, 'python')
        futures.append(future)
    for future in concurrent.futures.as_completed(futures):
        for line_num, line in future.result():
            print(f'Поток: строка {line_num}: {line}')

Пример 6: Поиск с игнорированием комментариев и пустых строк

Пример

with open('script.py', 'r', encoding='utf-8') as f:
    for line in f:
        stripped = line.strip()
        if not stripped or stripped.startswith('#'):
            continue
        if 'def ' in stripped:
            print(stripped)

Этот код выводит только объявления функций из Python-файла, пропуская комментарии и пустые строки.

Поиск строки в файле Python - comments

En
Python line find (python)