Извлечение глав из текста - PullRequest
3 голосов
/ 29 апреля 2019

Как и мой вопрос здесь, я хочу извлечь последовательности символов в строке с регулярным выражением в R. Я хочу извлечь разделы из текстового документа, в результате чего во фрейме данных, где каждый подразделрассматривается как собственный вектор, для дальнейшего Text Mining.Это мой пример данных:

chapter_one <- c("One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin.
1 Introduction
He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections. 
1.1 Futher
The bedding was hardly able to cover it and seemed ready to slide off any moment. 
1.1.1 This Should be Part of One Point One
His many legs, pitifully thin compared with the size of the rest of him, waved about helplessly as he looked.
1.2 Futher Fuhter
'What's happened to me?' he thought. It wasn't a dream. His room, a proper human room although a little too small, lay peacefully between its four familiar walls.")

Это мой ожидаемый результат:

chapter_id <- (c("1 Introduction", "1.1 Futher", "1.2 Futher Futher")) 
text <- (c("He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections.", "The bedding was hardly able to cover it and seemed ready to slide off any moment. His many legs, pitifully thin compared with the size of the rest of him, waved about helplessly as he looked.", "'What's happened to me?' he thought. It wasn't a dream. His room, a proper human room although a little too small, lay peacefully between its four familiar walls."))

chapter_one_df <- data.frame(chapter_id, text)

То, что я до сих пор пробовал, выглядит примерно так:

library(stringr)

regex_chapter_heading <- regex("
          [:digit:]     # Digit number 
                        # MISSING: Optional dot and optional second digit number 
          \\s           # Space
          ([[:alpha:]]) # Alphabetic characters (MISSING: can also contain punctuation, as in 'Introduction - A short introduction')
                     ", comments = TRUE)

read.table(text=gsub(regex_chapter_heading,"\\1:",chapter_one),sep=":")

Итакпока что это не приводит к ожидаемому результату - потому что, как указано, части Regex по-прежнему отсутствуют.Любая помощь высоко ценится!

1 Ответ

1 голос
/ 29 апреля 2019

Вы можете попробовать следующий подход: 1) заменить все строки, начинающиеся с трех чисел, разделенных точками (так как они являются продолжением предыдущих пунктов маркера), и 2) извлечь части, используя число + необязательная точка + число в качестве разделителя шаблон при захвате первых строк и строк, следующих за ними, в отдельные группы захвата:

library(stringr)
# Replace lines starting with N.N.N+ with space
chapter_one <- gsub("\\R\\d+(?:\\.\\d+){2,}\\s+[A-Z].*\\R?", " ", chapter_one, perl=TRUE)
# Split into IDs and Texts
data <- str_match_all(chapter_one, "(?sm)^(\\d+(?:\\.\\d+)?\\s+[A-Z][^\r\n]*)\\R(.*?)(?=\\R\\d+(?:\\.\\d+)?\\s+[A-Z]|\\z)")
# Get the chapter ID column
chapter_id <- trimws(data[[1]][,2])
# Get the text ID column
text <- trimws(data[[1]][,3])
# Create the target DF
chapter_one_df <- data.frame(chapter_id, text)

Выход:

         chapter_id
1    1 Introduction
2        1.1 Futher
3 1.2 Futher Fuhter
                                                                                                                                                                                              text
1                                       He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections.
2 The bedding was hardly able to cover it and seemed ready to slide off any moment.  His many legs, pitifully thin compared with the size of the rest of him, waved about helplessly as he looked.
3                               'What's happened to me?' he thought. It wasn't a dream. His room, a proper human room although a little too small, lay peacefully between its four familiar walls.

Шаблон \R\d+(?:\.\d+){2,}\s+[A-Z].*\R? используется для замены строк, которые вы хотите «исключить», пробелом:

  • \R - разрыв строки
  • \d+ - 1+ цифр
  • (?:\.\d+){2,} - два или более повторений . и 1+ цифр
  • \s+ - 1+ пробелов (замените на \h, чтобы соответствовать одному горизонтальному пробелу, или \h+, чтобы соответствовать им 1 или более)
  • [A-Z] - заглавная буква
  • .* - любые 0+ символов, кроме символов разрыва строки, как можно больше, до конца строки
  • \R? - дополнительная последовательность символов разрыва строки.

Второе регулярное выражение довольно сложное:

(?sm)^(\d+(?:\.\d+)?\s+[A-Z][^\r\n]*)\R(.*?)(?=\R\d+(?:\.\d+)?\s+[A-Z]|\z)

См. Демоверсию regex .

Детали

  • (?sm) - s делает . совпадением с любым символом, а m делает ^ совпадением начала строки
  • ^ - начало строки
  • (\d+(?:\.\d+)?\s+[A-Z][^\r\n]*) - Группа 1: одна или несколько цифр, затем 1 или 0 повторений . и 1+ цифр, 1+ пробелы, заглавная буква, любые 0+ символов, кроме символов CR и LF, столько же, сколько по возможности
  • \R - разрыв строки
  • (.*?) - Группа 2: любые 0+ символов, как можно меньше, до первого появления
    • \R\d+(?:\.\d+)?\s+[A-Z] - разрыв строки, одна или несколько цифр, затем 1 или 0 повторений . и 1+ цифр, 1+ пробелов, заглавная буква
    • | - или
    • \z - конец строки.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...