поиск строк с ключевыми словами на компьютере
import sys
from pathlib import Path
def find_matching_lines(input_phrase, search_directory, output_file, min_words=4):
"""
Находит уникальные строки, которые содержат как минимум два слова из входной фразы
и имеют минимальную длину.
"""
# Разбиваем входную фразу на отдельные слова
search_words = set(word.lower() for word in input_phrase.split() if len(word) > 2)
if len(search_words) < 2:
print("Фраза должна содержать хотя бы 2 значимых слова")
return set()
matching_lines = set()
for root, dirs, files in os.walk(search_directory):
for file in files:
if file.endswith('.txt'):
file_path = os.path.join(root, file)
try:
with open(file_path, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if len(line.split()) < min_words:
continue # Пропускаем короткие строки
line_lower = line.lower()
found_words = sum(1 for word in search_words if word in line_lower)
if found_words >= 2:
matching_lines.add(line)
except Exception as e:
print(f"Ошибка при чтении {file_path}: {e}")
# Сохраняем результаты
if matching_lines:
try:
with open(output_file, 'w', encoding='utf-8') as f:
for line in sorted(matching_lines):
f.write(line + '\n')
print(f"Найдено {len(matching_lines)} уникальных строк (мин. {min_words} слова)")
except Exception as e:
print(f"Ошибка при сохранении: {e}")
else:
print("Подходящие строки не найдены.")
return matching_lines
Найти еще
def main():
if len(sys.argv) > 1:
input_phrase = ' '.join(sys.argv[1:])
else:
input_phrase = input("фраза для поиска: ")
desktop_path = Path.home() / 'Desktop'
output_file = desktop_path / "найдены_строки.txt"
print(f"Поиск: '{input_phrase}'")
find_matching_lines(input_phrase, desktop_path, output_file, min_words=4)
if name == "main":
main()
> почему то эта программа также находит строки в которых нет ключевых слов
Анализ проблемы в коде
тогда Давай разберёмся, почему программа находит строки, в которых, по твоему мнению, нет ключевых слов. Я проанализировал код и нашёл потенциальную причину: проверка на подстроки вместо целых слов.
Ключевой момент в коде:
В строке found_words = sum(1 for word in search_words if word in line_lower) программа проверяет, содержится ли каждое ключевое слово (из search_words) как подстрока в строке (line_lower).
Это означает, что если ключевое слово является частью другого слова, оно всё равно засчитывается. Например:
Ключевое слово: "cat".
Строка: "I love caterpillar" — "cat" найдено как подстрока в "caterpillar", хотя "cat" не является отдельным словом.
Или: "the" в "theoretical" — засчитывается, даже если "the" — это часть слова "theoretical".
Таким образом, программа может "находить" строки, где ключевые слова отсутствуют как отдельные слова, но присутствуют как фрагменты в других словах. Это приводит к ложным срабатываниям, особенно если фраза содержит короткие или распространённые слова (например, "the", "and", "is").
Почему это происходит?
Код не проверяет границы слов (например, пробелы или знаки препинания вокруг слова).
Он просто ищет подстроки, что делает поиск менее точным.
Как исправить?
Чтобы исправить, нужно изменить логику поиска: проверять, что ключевое слово является отдельным словом в строке (с учётом границ). Вот улучшенная версия функции find_matching_lines. Я добавил использование регулярных выражений для точного поиска слов
import os
import sys
import re # Добавляем для регулярных выражений
from pathlib import Path
def find_matching_lines(input_phrase, search_directory, output_file, min_words=4):
"""
Находит уникальные строки, которые содержат как минимум два слова из входной фразы
и имеют минимальную длину. Исправлено: проверка на целые слова, а не подстроки.
"""
# Разбиваем входную фразу на отдельные слова
search_words = set(word.lower() for word in input_phrase.split() if len(word) > 2)
if len(search_words) < 2:
print("Фраза должна содержать хотя бы 2 значимых слова")
return set()
matching_lines = set()
for root, dirs, files in os.walk(search_directory):
for file in files:
if file.endswith('.txt'):
file_path = os.path.join(root, file)
try:
with open(file_path, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if len(line.split()) < min_words:
continue # Пропускаем короткие строки
line_lower = line.lower()
found_words = 0
for word in search_words:
# Используем регулярное выражение для поиска целого слова (с границами)
# \b - граница слова (пробел, начало/конец строки и т.д.)
if re.search(r'\b' + re.escape(word) + r'\b', line_lower):
found_words += 1
if found_words >= 2:
matching_lines.add(line)
except Exception as e:
print(f"Ошибка при чтении {file_path}: {e}")
# Сохраняем результаты
if matching_lines:
try:
with open(output_file, 'w', encoding='utf-8') as f:
for line in sorted(matching_lines):
f.write(line + '\n')
print(f"Найдено {len(matching_lines)} уникальных строк (мин. {min_words} слова)")
except Exception as e:
print(f"Ошибка при сохранении: {e}")
else:
print("Подходящие строки не найдены.")
return matching_lines
Что изменилось в коде
Добавлен импорт re для регулярных выражений.
Изменена проверка: if re.search(r'\b' + re.escape(word) + r'\b', line_lower) — теперь ищется точное совпадение слова с границами (\b). re.escape защищает от специальных символов в словах.
Это предотвратит ложные срабатывания: "cat" не найдётся в "caterpillar", но найдётся в "the cat is here".
Дополнительные советы
Тестируй: Попробуй с фразой вроде "the quick brown fox" и строкой "the quick brown fox jumps over" (должно найтись) vs. "theoretical quick brown" (не должно, если "fox" нет как слово).
Производительность: Для больших файлов регулярки могут быть медленнее, но для desktop-поиска это нормально.
Если проблема persists, проверь входные данные: убедись, что search_words корректно формируется (выведи его на печать для отладки).
Если это не решит проблему или нужны ещё уточнения, дай знать
Свидетельство о публикации №125091306362