Подтвердить что ты не робот

Извлеките информацию внутри всех скобок в R

У меня есть строка символов и что нужно извлечь информацию из нескольких круглых скобок. В настоящее время я могу извлечь информацию из последней круглой скобки с помощью приведенного ниже кода. Как мне это сделать, чтобы он извлекал несколько круглых скобок и возвращал их как вектор?

j <- "What kind of cheese isn't your cheese? (wonder) Nacho cheese! (groan) (Laugh)"                                                          
sub("\\).*", "", sub(".*\\(", "", j)) 

Текущий выход:

[1] "Laugh"

Требуемый вывод:

[1] "wonder" "groan"  "Laugh" 
4b9b3361

Ответ 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"