Поиск слов (точных совпадений) в нескольких текстах с использованием Python

Вопрос: Я хочу, чтобы пользователь выбирал и открывал несколько текстов и выполнял поиск точных совпадений в текстах. Я хочу, чтобы кодировка была unicode. Если я ищу "кот", я хочу, чтобы он нашел "cat", "cat", ".cat", но не "каталог". Я не знаю, как позволить пользователю искать два слова ("кошка" или "собака") во всех текстах одновременно????? Может

Вопрос:

Я хочу, чтобы пользователь выбирал и открывал несколько текстов и выполнял поиск точных совпадений в текстах. Я хочу, чтобы кодировка была unicode.

Если я ищу “кот”, я хочу, чтобы он нашел “cat”, “cat”, “.cat”, но не “каталог”.

Я не знаю, как позволить пользователю искать два слова (“кошка” или “собака”) во всех текстах одновременно????? Может быть, я могу использовать RE?

До сих пор я только что дал пользователю возможность вставить путь в каталог, содержащий текстовые файлы для поиска. Теперь я хочу, чтобы пользователь (raw_input) искал два слова во всех текстах, а затем печатал и сохраните результаты (например, “search_word_1” и “search_word_2”, найденные в файле document1.txt, “search_word_2”, найденные в документе4.txt) в отдельном документе (search_words).

import re, os path = raw_input(«insert path to directory :») ex_library = os.listdir(path) search_words = open(«sword.txt», «w») # File or maybe list to put in the results thelist = [] for texts in ex_library: f = os.path.join(path, texts) text = open(f, «r») textname = os.path.basename(texts) print textname for line in text.read(): text.close() Лучший ответ:

В этом случае регулярные выражения являются подходящим инструментом.

Я хочу, чтобы он нашел “cat”, “cat”, “.cat”, но не “каталог”.

Выкройка: r’bcatb’

b соответствует границе слова.

как разрешить пользователю искать два слова (“кошка” или “собака”) во всех текстах одновременно

Выкройка: r’bcatb|bdogb’

Чтобы напечатать «filename: <words that are found in it>»:

#!/usr/bin/env python import os import re import sys def fgrep(words, filenames, encoding=’utf-8′, case_insensitive=False): findwords = re.compile(«|».join(r»b%sb» % re.escape(w) for w in words), flags=re.I if case_insensitive else 0).findall for name in filenames: with open(name, ‘rb’) as file: text = file.read().decode(encoding) found_words = set(findwords(text)) yield name, found_words def main(): words = [w.decode(sys.stdin.encoding) for w in sys.argv[1].split(«,»)] filenames = sys.argv[2:] # the rest is filenames for filename, found_words in fgrep(words, filenames): print «%s: %s» % (os.path.basename(filename), «,».join(found_words)) main()

Пример:

$ python findwords.py ‘cat,dog’ /path/to/*.txt

Альтернативные решения

Чтобы не читать весь файл в памяти:

import codecs … with codecs.open(name, encoding=encoding) as file: found_words = set(w for line in file for w in findwords(line))

Вы также можете распечатать найденные слова в контексте, который они нашли, например, печатать строки с выделенными словами:

from colorama import init # pip install colorama init(strip=not sys.stdout.isatty()) # strip colors if stdout is redirected from termcolor import colored # pip install termcolor highlight = lambda s: colored(s, on_color=’on_red’, attrs=[‘bold’, ‘reverse’]) … regex = re.compile(«|».join(r»b%sb» % re.escape(w) for w in words), flags=re.I if case_insensitive else 0) for line in file: if regex.search(line): # line contains words line = regex.sub(lambda m: highlight(m.group()), line) yield line Ответ №1

Вам нужно разделить текст в каждом файле на пробелы и пунктуацию. После этого вы можете просто искать слова, которые ищете в остальном списке. Вам также нужно преобразовать все в нижний регистр, если вы также не хотите, чтобы поиск с учетом регистра.

Ответ №2

Некоторая (возможно полезная) информация в дополнение к существующим ответам:

Вы должны знать, что то, что пользователь означает, когда он думает о “характере” (= grapheme), не всегда совпадает с символом Unicode, а некоторые графемы могут быть представлены символами Unicode более чем одним уникальным способом (например, составной символ против базового символа + комбинация метки).

Чтобы выполнить поиск на основе графем (= то, чего ожидает пользователь в большинстве случаев), а не для определенных последовательностей символов Unicode, вам необходимо нормализовать строки перед тем, как искать.

Оцените статью
Добавить комментарий