Поиск подстроки для строк из нескольких слов - Python

Я хочу проверить набор предложений и посмотреть, встречается ли в предложениях несколько начальных слов. но я хочу избежать использования for seed in line потому что это сказал бы, что семя слово ring появился бы в документе со словом bring,

Я также хочу проверить, нравятся ли выражения из нескольких слов (MWE) word with spaces появляется в документе.

Я пробовал это, но это очень медленно, есть ли более быстрый способ сделать это?

seed = ['words with spaces', 'words', 'foo', 'bar', 
        'bar bar', 'foo foo foo bar', 'ring']

 docs = ['these are words with spaces but the drinks are the bar is also good', 
    'another sentence at the foo bar is here', 
    'then a bar bar black sheep, 
    'but i dont want this sentence because there is just nothing that matches my list',
    'i forgot to bring my telephone but this sentence shouldn't be in the seeded docs too']

docs_seed = []
for d in docs:
  toAdd = False
  for s in seeds:
    if " " in s:
      if s in d:
        toAdd = True
    if s in d.split(" "):
      toAdd = True
    if toAdd == True:
      docs_seed.append((s,d))
      break
print docs_seed

Желаемый вывод должен быть таким:

[('words with spaces','these are words with spaces but the drinks are the bar is also good')
('foo','another sentence at the foo bar is here'), 
('bar', 'then a bar bar black sheep')]

2 ответа

Решение

Попробуйте использовать регулярное выражение:

import re

pattern = re.compile(r'\b(?:' + '|'.join(re.escape(s) for s in seed) + r')\b')
pattern.findall(line)

\b соответствует началу или концу слова (последовательность символов слова).

Пример:

>>> for line in docs:
...     print pattern.findall(line)
... 
['words with spaces', 'bar']
['foo', 'bar']
['bar', 'bar']
[]
[]

Это должно работать и быть несколько быстрее, чем ваш текущий подход:

docs_seed = []
for d in docs:
    for s in seed:
        pos = d.find(s)
        if not pos == -1 and (d[pos - 1] == " " 
               and (d[pos + len(s)] == " " or pos + len(s) == len(d))):
            docs_seed.append((s, d))
            break

find дает нам позицию seed Значение в документе (или -1, если оно не найдено), мы проверяем, что символы до и после значения являются пробелами (или строка заканчивается после подстроки). Это также исправляет ошибку в исходном коде, когда многословные выражения не нужно начинать или заканчивать на границе слова - ваш исходный код будет соответствовать "words with spaces" для входа, как "swords with spaces",

Другие вопросы по тегам