Tengo un vector de entrada de la siguiente manera:

input <- c("fdsfs iwantthis (1,1,1,1) fdsaaa   iwantthisaswell (2,3,4,5)", "fdsfs thistoo (1,1,1,1)")

Y me gustaría usar una expresión regular para extraer lo siguiente:

> output
[1] "iwantthis iwantthisaswell" "thistoo"

He logrado extraer cada palabra que está antes de un paréntesis de apertura. Intenté esto para obtener solo la primera palabra:

> gsub(".*?[[:space:]](.*?)[[:space:]]\\(.*", "\\1", input)
[1] "iwantthis" "thistoo"  

Pero no puedo hacer que funcione para múltiples ocurrencias:

    > gsub(".*?[[:space:]](.*?)[[:space:]]\\(.*?[[:space:]](.*?)[[:space:]]\\(.*", "\\1 \\2", input)
[1] "iwantthis iwantthisaswell" "fdsfs thistoo (1,1,1,1)"  

Lo más cercano que he logrado es lo siguiente:

library(stringr)
> str_extract_all(input, "(\\S*)\\s\\(")
[[1]]
[1] "iwantthis ("       "iwantthisaswell ("

[[2]]
[1] "thistoo ("

Estoy seguro de que me falta algo en mi expresión regular (no es tan bueno), pero ¿qué?

1
User2321 10 sep. 2018 a las 15:25

3 respuestas

La mejor respuesta

Puede usar

> sapply(str_extract_all(input, "\\S+(?=\\s*\\()"), paste, collapse=" ")
[1] "iwantthis iwantthisaswell" "thistoo"

Consulte la demostración de expresiones regulares. \\S+(?=\\s*\\() extraerá todos los fragmentos de espacios que no sean espacios en blanco de un texto antes de un carácter ( precedido por 0+ espacios en blanco. sapply con paste unirá las coincidencias encontradas con un espacio (con collapse=" ").

Detalles del patrón

  • \S+ - 1 o más caracteres que no son espacios en blanco
  • (?=\s*\(): una anticipación positiva ((?=...)) que requiere la presencia de más de 0 espacios en blanco (\s*) y luego un ( carácter (\() inmediatamente para El derecho de la posición actual.
3
Wiktor Stribiżew 10 sep. 2018 a las 12:32

Esto funciona en R:

gsub('\\w.+? ([^\\s]+) \\(.+?\\)','\\1', input, perl=TRUE)

Resultado:

[1] "iwantthis iwantthisaswell" "thistoo" 

ACTUALIZADO para trabajar para el caso general. P.ej. ahora encuentra "i_wantthisaswell2" buscando en no espacios entre las otras coincidencias.

Usando otras entradas de caso general sugeridas:

general_cases <- c("fdsfs iwantthis (1,1,1,1) fdsaaa   iwantthisaswell (2,3,4,5)", 
                   "fdsfs thistoo (1,1,1,1) ",
                   "GaGa iwant_this (1,1,1,1)", 
                   "lal2!@#$%^&*()_+a i_wantthisaswell2 (2,3,4,5)")
gsub('\\w.+? ([^\\s]+) \\(.+?\\)','\\1', general_cases, perl=TRUE)

Resultados:

[1] "iwantthis iwantthisaswell" "thistoo "                 
[3] "iwant_this"                "i_wantthisaswell2"        
0
krads 10 sep. 2018 a las 14:10

Aquí hay una opción usando base R

unlist(regmatches(input, gregexpr("\\w+(?= \\()", input, perl = TRUE)))
#[1] "iwantthis"       "iwantthisaswell" "thistoo"  
1
akrun 10 sep. 2018 a las 14:56