Как вытащить текстовые фрагменты вокруг определенных слов? - PullRequest
1 голос
/ 10 июля 2019

У меня большой текстовый файл, и я пытаюсь извлечь каждый экземпляр конкретного слова, а также 15 слов с каждой стороны.Я сталкиваюсь с проблемой, когда есть два экземпляра этого слова в пределах 15 слов друг от друга, которые я пытаюсь получить как один большой фрагмент текста.

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

def occurs(word1, word2, filename):
    import os

    infile = open(filename,'r')     #opens file, reads, splits into lines
    lines = infile.read().splitlines()
    infile.close()
    wordlist = [word1, word2]       #this list allows for multiple words
    wordsString = ''.join(lines)      #splits file into individual words
    words = wordsString.split()

    f = open(filename, 'w')
    f.write("start")
    f.write(os.linesep)

    for word in wordlist:       
        matches = [i for i, w in enumerate(words) if w.lower().find(word) != -1] 

        for m in matches:        
            l = " ".join(words[m-15:m+16])
            f.write(f"...{l}...")       #writes the data to the external file
            f.write(os.linesep)
    f.close

До сих пор, когда два одинаковых слова находятся слишком близко друг к другу, программа просто не запускается на одном из них.Вместо этого я хочу получить более длинный фрагмент текста, который на 15 слов располагается позади и перед самыми дальними словами вперед и назад

Ответы [ 2 ]

1 голос
/ 10 июля 2019

Как всегда, различные решения доступны здесь. Самое интересное - это рекурсивный wordFind, где он ищет следующие 15 слов и, если находит целевое слово, он может вызвать сам себя.

Более простым, хотя, возможно, и неэффективным решением было бы добавлять слова по одному:

for m in matches:        
            l = " ".join(words[m-15:m])
            i = 1
            while i < 16:
                        if (words[m+i].lower() == word):
                                    i=1
                        else:
                                    l.join(words[m+(i++)])
            f.write(f"...{l}...")       #writes the data to the external file
            f.write(os.linesep)

Или, если вы хотите удалить последующее использование ...

bExtend = false;
for m in matches:
        if (!bExtend):
                    l = " ".join(words[m-15:m])
                    f.write("...")
        bExtend = false
        i = 1
        while (i < 16):
                    if (words[m].lower() == word):
                                l.join(words[m+i])
                                bExtend = true
                                break
                    else:
                                l.join(words[m+(i++)])
        f.write(l)
        if (!bExtend):
                    f.write("...") 
                    f.write(os.linesep)

Обратите внимание, не проверял, поэтому может потребоваться немного отладки. Но суть ясна: добавляйте слова по частям и расширяйте процесс сложения, когда встречается целевое слово. Это также позволяет расширять другие целевые слова, отличные от текущего, с небольшим добавлением ко второму условному условию if.

0 голосов
/ 10 июля 2019

Этот фрагмент получит количество слов вокруг выбранного ключевого слова. Если есть несколько ключевых слов вместе, он присоединится к ним:

s = '''xxx I have a large txt file and I'm xxx trying to pull out every instance of a specific word, as well as the 15 words on either side. I'm running into a problem when there are two instances of that word within 15 words of each other, which I'm trying to get as one large snippet of text.
I'm trying to xxx get chunks of text to analyze about a specific topic. So far, I have working code for all instances except the scenario mentioned above. xxx'''

words = s.split()

from itertools import groupby, chain

word = 'xxx'

def get_snippets(words, word, l):
    snippets, current_snippet, cnt = [], [], 0
    for v, g in groupby(words, lambda w: w != word):
        w = [*g]
        if v:
            if len(w) < l:
                current_snippet += [w]
            else:
                current_snippet += [w[:l] if cnt % 2 else w[-l:]]
                snippets.append([*chain.from_iterable(current_snippet)])
                current_snippet = [w[-l:] if cnt % 2 else w[:l]]
                cnt = 0
            cnt += 1
        else:
            if current_snippet:
                current_snippet[-1].extend(w)
            else:
                current_snippet += [w]

    if current_snippet[-1][-1] == word or len(current_snippet) > 1:
        snippets.append([*chain.from_iterable(current_snippet)])

    return snippets

for snippet in get_snippets(words, word, 15):
    print(' '.join(snippet))

Печать:

xxx I have a large txt file and I'm xxx trying to pull out every instance of a specific word, as well as the 15
other, which I'm trying to get as one large snippet of text. I'm trying to xxx get chunks of text to analyze about a specific topic. So far, I have working
topic. So far, I have working code for all instances except the scenario mentioned above. xxx

С одинаковыми данными и различной длиной:

for snippet in get_snippets(words, word, 2):
    print(' '.join(snippet))

Печать:

xxx and I'm
I have xxx trying to
trying to xxx get chunks
mentioned above. xxx
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...