Поиск строки в файле в 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())
Расширенные примеры поиска строки в файле
Пример 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-файла, пропуская комментарии и пустые строки.