Extraer información dentro de todos los paréntesis en R

Tengo una cadena de caracteres y qué extraer la información dentro de múltiples paréntesis. Actualmente puedo extraer la información del último paréntesis con el siguiente código. ¿Cómo lo haría para que extraiga múltiples paréntesis y regrese como un vector?

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

La salida actual es:

 [1] "Laugh" 

La salida deseada es:

 [1] "wonder" "groan" "Laugh" 

Aquí hay un ejemplo:

 > gsub("[\\(\\)]", "", regmatches(j, gregexpr("\\(.*?\\)", j))[[1]]) [1] "wonder" "groan" "Laugh" 

Creo que esto debería funcionar bien:

 > regmatches(j, gregexpr("(?=\\().*?(?<=\\))", j, perl=T))[[1]] [1] "(wonder)" "(groan)" "(Laugh)" 

pero los resultados incluyen paréntesis ... ¿por qué?

Esto funciona:

 regmatches(j, gregexpr("(?<=\\().*?(?=\\))", j, perl=T))[[1]] 

Gracias @MartinMorgan por el comentario.

Usando el paquete stringr podemos reducir esto un poco.

 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 usa los regmatches pero actualmente estoy usando 2.13 por lo que no tengo acceso a esa función en este momento. Esto agrega la dependencia de stringr pero creo que es un poco más fácil trabajar con él y el código es un poco más claro (bueno ... tan claro como usar expresiones regulares puede ser ...)

Editar: también podríamos intentar algo como esto:

 re <- "\\(([^()]+)\\)" gsub(re, "\\1", str_extract_all(j, re)[[1]]) 

Este funciona definiendo una subexpresión marcada dentro de la expresión regular. Extrae todo lo que coincide con la expresión regular y luego gsub extrae solo la parte dentro de la subexpresión.

Usar rex puede hacer que este tipo de tarea sea un poco más simple.

 matches <- re_matches(j, rex( "(", capture(name = "text", except_any_of(")")), ")"), global = TRUE) matches[[1]]$text #>[1] "wonder" "groan" "Laugh" 

Creo que hay básicamente tres formas fáciles de extraer múltiples grupos de captura en R (sin usar sustitución); str_match_all , str_extract_all , y regmatches/gregexpr combo.

Me gusta la expresión regular de @ kohske, que busca un paréntesis abierto ?<=\\( , busca un paréntesis de cierre ?=\\) , y toma todo en el medio (perezosamente) .+? , en otras palabras (?<=\\().+?(?=\\))

Usando la misma expresión regular:

str_match_all devuelve la respuesta como una matriz .

 str_match_all(j, "(?<=\\().+?(?=\\))") [,1] [1,] "wonder" [2,] "groan" [3,] "Laugh" # Subset the matrix like this.... str_match_all(j, "(?<=\\().+?(?=\\))")[[1]][,1] [1] "wonder" "groan" "Laugh" 

str_extract_all devuelve la respuesta como una lista .

 str_extract_all(j, "(?<=\\().+?(?=\\))") [[1]] [1] "wonder" "groan" "Laugh" #Subset the list... str_extract_all(j, "(?<=\\().+?(?=\\))")[[1]] [1] "wonder" "groan" "Laugh" 

regmatches/gregexpr también devuelve la respuesta como una lista . Como esta es una opción R base, algunas personas la prefieren. Tenga en cuenta el perl = TRUE recomendado perl = TRUE .

 regmatches(j, gregexpr( "(?<=\\().+?(?=\\))", j, perl = T)) [[1]] [1] "wonder" "groan" "Laugh" #Subset the list... regmatches(j, gregexpr( "(?<=\\().+?(?=\\))", j, perl = T))[[1]] [1] "wonder" "groan" "Laugh" 

Con suerte, la comunidad SO corregirá / editará esta respuesta si he caracterizado erróneamente las opciones más populares.