Несмотря на часто выражаемую антипатию к регулярным выражениям со стороны многих в сообществе Python, они действительно являются ценным инструментом для соответствующих случаев использования - которые, безусловно, включают в себя определение слов и фраз (благодаря \b
" «граница слова» в шаблонах регулярных выражений - альтернативы, основанные на обработке строк, представляют собой гораздо большую проблему, например, .split()
использует пробел в качестве разделителя и, таким образом, досадно оставляет пунктуацию присоединенной к смежным словам и т. д., и т. д.).
Если RE в порядке, я бы порекомендовал что-то вроде:
import re
import sys
def main():
if len(sys.argv) != 3:
print("Usage: %s fileofstufftofind filetofinditin" % sys.argv[0])
sys.exit(1)
with open(sys.argv[1]) as f:
patterns = [r'\b%s\b' % re.escape(s.strip()) for s in f]
there = re.compile('|'.join(patterns))
with open(sys.argv[2]) as f:
for i, s in enumerate(f):
if there.search(s):
print("Line %s: %r" % (i, s))
main()
первый аргумент (путь) текстового файла со словами или фразами для поиска, по одному на строку, а второй аргумент (путь) текстового файла для поиска. При желании легко сделать регистр нечувствительным к поиску (возможно, опционально на основе параметра командной строки) и т. Д. И т. Д.
Некоторые пояснения для читателей, которые не знакомы с РЭ ...:
Элемент \b
в элементах patterns
гарантирует, что случайных совпадений не будет (если вы ищете "кошку" или "собаку", вы не увидите случайного попадания с "каталогом" или «underdog», и вы не пропустите хит «Кошка, улыбаясь, убежал», если рассудите, что слово «кошка», включая запятую; -).
Элемент |
означает or
, например, из текстового файла с содержимым (две строки)
cat
dog
это сформирует шаблон '\bcat\b|\bdog\b'
, который будет определять местонахождение "кошки" или "собаки" (как отдельные слова, игнорируя пунктуацию, но отклоняя попадания в более длинные слова).
re.escape
не содержит знаков препинания, поэтому оно соответствует буквально, а не имеет особого значения, как это обычно бывает в шаблоне RE.