Абзац NLTK corpus reader

#text-files #nltk

#текстовые файлы #nltk

Вопрос:

Я попытался скопировать содержимое вставки из документа word (.docx) в файл .txt и заставил его прочитать nltk corpus reader, чтобы найти номер абзаца. Он возвращает почти 30 абзацев как один абзац. Я вручную ввел разрыв строки в .txt-файл, и он вернул 30 абзацев.

 import nltk
corpusReader = nltk.corpus.reader.plaintext.PlaintextCorpusReader(".", "d.txt")
print "Paragraphs =", len(corpusReader.paras())
  
  1. Возможно ли, чтобы PlaintextCorpus reader читал .docx?
  2. Как сохранить разрыв строки при копировании и вставке из .docx в .txt?
  3. Есть ли способ с помощью python, где я открываю .txt-файл и нахожу ?!или . или … а затем несколько пробелов (4 в количестве) и нажмите «enter», чтобы автоматически создать разрыв строки? разрыв.

Редактировать 1.

Прошел путь para_block_reader=read_line_block, но это всегда приводит к увеличению количества абзацев.

 import nltk
from nltk.corpus.reader.util import *
corpusReader = nltk.corpus.reader.plaintext.PlaintextCorpusReader(".", "d.txt",para_block_reader=read_line_block)
print "Paragraphs =", len(corpusReader.paras())
  

Комментарии:

1. Вы получаете дополнительный абзац, потому что последняя строка в вашем файле заканчивается новой строкой. Это нормально, и вы можете просто решить смириться с этим (просто напишите код, который не захлебывается пустыми абзацами).

2. Не редактируйте свой вопрос, чтобы включить ответ в текст вопроса. Предполагается, что этот сайт работает не так. Достаточно принять ответ (и лучше, поскольку ответ может быть поддержан и отредактирован независимо от вашего вопроса.

Ответ №1:

Программа чтения текстового корпуса может читать только текстовые файлы. Существуют библиотеки Python, которые могут читать docx, но это не решит вашу проблему, которая заключается в том, что Word разделяет абзацы одним разрывом строки, но в текстовых документах граница абзаца традиционно понимается как пустая строка, то есть две последовательные новые строки. Другими словами, ваш метод экспорта сохраняет новые строки; просто их недостаточно.

Итак, есть простой способ исправить ваши тексты так, чтобы абзацы распознавались без дополнительных действий: после того, как вы записали свой текстовый файл (что вы можете сделать из Save As... меню Word или путем вырезания и вставки), выполните его последующую обработку следующим образом (добавьте encoding= аргументы по мере необходимости):

 with open("my_plaintext.txt") as oldfile:
    content = oldfile.read()

content = re.sub("n", "nn", content)

with open("my_plaintext_fixed.txt", "w") as newfile:
    newfile.write(content)
  

Теперь вы можете прочитать myplaintext_fixed.txt" with the PlaintextCorpusReader`, и все будет работать так, как ожидалось.

Ответ №2:

Исходный код для PlainTextCorpus reader — это первый класс, определенный на этой странице, он довольно прост.

У него есть подкомпоненты, если вы не выделяете их в конструкторе, он использует значения по умолчанию NLTK

  • para_block_reader (по умолчанию: read_blankline_block ), в котором указано, как документ разбит на абзацы.
  • sentence_tokenizer (по умолчанию: English Punkt), в котором говорится, как разбить абзац на предложения
  • word_tokenizer (по умолчанию WordPunctTokenizer() ), в котором говорится, как разбить предложение на токены (слова и символы).

Обратите внимание, что значения по умолчанию могут меняться в разных версиях NLTK. Я чувствую, что по умолчанию word_tokenizer использовался токенизатор Penn.

Re: 1.

Ни один читатель PlaintextCorpus не может читать Docx. Он читает только обычный текст. Я уверен, что вы можете найти библиотеку python для ее преобразования

Re 2

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

Re 3

Да, вы можете выполнить поиск и замену с помощью регулярных выражений.

  import re
 def breakup(mystring):
      return re.replace(mystring, r"(.|!|...)    ", "n")
  

Но, возможно, вместо этого вы захотите поменять местами свой para_block_reader или sent_tokenizer