Извлечение текста между определенными символами с использованием регулярного выражения в R

У меня есть ряд выражений, таких как:

"<i>the text I need to extract</i></b></a></div>"

Мне нужно извлечь текст между символами <i> и </i> ". Это результат:

"the text I need to extract"

В настоящий момент я использую gsub в R, чтобы вручную удалить все символы, которые не являются текстом. Тем не менее, я хотел бы использовать регулярное выражение для выполнения задания. Кто-нибудь знает регулярное выражение для извлечения между <i> и </i>?

Спасибо.

Ответ 1

Если есть только один <i>...</i>, как в примере, сопоставьте все до <i> и все от </i> вперед и замените их как пустой строкой:

x <- "<i>the text I need to extract</i></b></a></div>"
gsub(".*<i>|</i>.*", "", x)

даяние:

[1] "the text I need to extract"

Если в одной строке может быть несколько вхождений, попробуйте:

library(gsubfn)
strapplyc(x, "<i>(.*?)</i>", simplify = c)

давая то же самое в этом примере.

Ответ 2

В этом подходе используется пакет, который я поддерживаю qdapRegex, который не является регулярным выражением, но может быть полезен для вас или будущих поисковиков. Функция rm_between позволяет пользователю извлекать текст между левой и правой границей и необязательно включать их. Этот подход прост в том, что вам не нужно думать о конкретном регулярном выражении, только о точном левом и правом границах:

library(qdapRegex)

x <- "<i>the text I need to extract</i></b></a></div>"

rm_between(x, "<i>", "</i>", extract=TRUE)

## [[1]]
## [1] "the text I need to extract"

Я хотел бы указать, что может быть более надежным использовать html-парсер для этого задания.

Ответ 3

Если это html (как он выглядит), вы должны использовать html-парсер. Пакет XML может сделать это

library(XML)
x <- "<i>the text I need to extract</i></b></a></div>"
xmlValue(getNodeSet(htmlParse(x), "//i")[[1]])
# [1] "the text I need to extract"

Во всем html-документе вы можете использовать

doc <- htmlParse(x)
sapply(getNodeSet(doc, "//i"), xmlValue)

Ответ 4

Вы можете использовать следующий подход с gregexpr и regmatches, если вы не знаете количество совпадений в строке.

vec <- c("<i>the text I need to extract</i></b></a></div>",
         "abc <i>another text</i> def <i>and another text</i> ghi")

regmatches(vec, gregexpr("(?<=<i>).*?(?=</i>)", vec, perl = TRUE))
# [[1]]
# [1] "the text I need to extract"
# 
# [[2]]
# [1] "another text"     "and another text"

Ответ 5

<i>((?:(?!<\/i>).)*)<\/i>

Это должно сделать это за вас.