Решение состоит в том, чтобы использовать суффиксные деревья, чтобы получить позиции каждого упоминания ключевого слова, а затем обработать перекрытие, как предложено @EricDuminil.
Вот моя функция для извлечения позиций kws
ключевых слов в текстовом источникеtxt
:
from suffix_trees import STree
def findMentions(txt, kws):
st = STree.STree(txt)
spans = []
for kw in kws:
starts = st.find_all(kw)
spans.extend([(item, item+len(kw)) for item in starts])
bounds = handleOverlap(spans)
return bounds
и вот функция для обработки перекрывающихся позиций символов:
def handleOverlap(spans):
del_in = []
for x in spans:
if spans.index(x) in del_in: continue
for y in spans:
if spans.index(y) in del_in: continue
if x == y: continue
if len(set(list(range(x[0],x[1]+1))) & set(list(range(y[0],y[1]+1)))) > 0:
if len(list(range(x[0],x[1]+1))) > len(list(range(y[0],y[1]+1))):
del_in.append(spans.index(y))
spans.pop(spans.index(y))
elif len(list(range(y[0],y[1]+1))) > len(list(range(x[0],x[1]+1))):
del_in.append(spans.index(x))
spans.pop(spans.index(x))
return spans
Мне просто нужно было добавить пробелы в оба конца каждого ключевого слова, чтобы избежать получения словсодержит ключевое слово, например, «нефтедоллар».Результатом являются неперекрывающиеся начальная и конечная позиции для самых длинных из упомянутых ключевых слов.