Извлеките информацию внутри всех скобок в R
У меня есть строка символов и что нужно извлечь информацию из нескольких круглых скобок. В настоящее время я могу извлечь информацию из последней круглой скобки с помощью приведенного ниже кода. Как мне это сделать, чтобы он извлекал несколько круглых скобок и возвращал их как вектор?
j <- "What kind of cheese isn't your cheese? (wonder) Nacho cheese! (groan) (Laugh)"
sub("\\).*", "", sub(".*\\(", "", j))
Текущий выход:
[1] "Laugh"
Требуемый вывод:
[1] "wonder" "groan" "Laugh"
Ответы
Ответ 1
Вот пример:
> gsub("[\\(\\)]", "", regmatches(j, gregexpr("\\(.*?\\)", j))[[1]])
[1] "wonder" "groan" "Laugh"
Я думаю, что это должно хорошо работать:
> regmatches(j, gregexpr("(?=\\().*?(?<=\\))", j, perl=T))[[1]]
[1] "(wonder)" "(groan)" "(Laugh)"
но результаты включают скобки... почему?
Это работает:
regmatches(j, gregexpr("(?<=\\().*?(?=\\))", j, perl=T))[[1]]
Спасибо @MartinMorgan за комментарий.
Ответ 2
Используя пакет stringr, мы можем немного уменьшить это.
library(stringr)
# Get the parenthesis and what is inside
k <- str_extract_all(j, "\\([^()]+\\)")[[1]]
# Remove parenthesis
k <- substring(k, 2, nchar(k)-1)
@kohske использует regmatches, но в настоящее время я использую 2.13, поэтому на данный момент у меня нет доступа к этой функции. Это добавляет зависимость от stringr, но я думаю, что с ним немного легче работать, а код немного понятнее (ну... так же ясно, как использование регулярных выражений может быть...)
Изменить: мы могли бы попробовать что-то вроде этого -
re <- "\\(([^()]+)\\)"
gsub(re, "\\1", str_extract_all(j, re)[[1]])
Это работает, определяя выраженное подвыражение внутри регулярного выражения. Он извлекает все, что соответствует регулярному выражению, а затем gsub извлекает только часть внутри подвыражения.
Ответ 3
Использование rex может сделать этот тип задачи немного проще.
matches <- re_matches(j,
rex(
"(",
capture(name = "text", except_any_of(")")),
")"),
global = TRUE)
matches[[1]]$text
#>[1] "wonder" "groan" "Laugh"