2012-08-31 10 views
10

Tengo una solicitud extraña con expresiones regulares en R. Tengo un vector de cadenas de caracteres donde algunos tienen múltiples períodos finales. Quiero reemplazar estos períodos por espacios. El ejemplo y el resultado deseado debe dejar claro lo que busco (tal vez tengo que atacar con lo que doy para reemplazar argumento más que el argumento patrón de gsub):reemplazar períodos finales con espacios

Ejemplo y los intentos:

x <- c("good", "little.bad", "really.ugly......") 
gsub("\\.$", " ", x) 
    #produces this 
    #[1] "good"    "little.bad"  "really.ugly..... " 
gsub("\\.+$", " ", x) 
    #produces this 
    #[1] "good"   "little.bad" "really.ugly " 

resultado deseado

[1] "good"    "little.bad"  "really.ugly  " 

así el vector original (x) tenía la última cadena con 6 puntos al final así que me gustaría 6 de spa sin tocar el período entre real y feo. Sé que el $ mira hacia el final pero no puede pasar esto.

Respuesta

16

Prueba esto:

gsub("\\.(?=\\.*$)", " ", mystring, perl=TRUE) 

Explicación:

\. # Match a dot 
(?= # only if followed by 
\.* # zero or more dots 
$ # until the end of the string 
) # End of lookahead assertion. 
+0

Obtengo 'expresión regular no válida '\. (? = \. * $)', Razón 'Regexp no válida' –

+0

@DavidRobinson: Dentro de una cadena, necesita duplicar las barras diagonales inversas. –

+2

+1 Edité tu respuesta para mostrar cómo se traduce a R. – Andrie

2

Mientras esperaba a una solución de expresiones regulares que tiene sentido que decidí venir a una forma sin sentido para resolver esto:

messy.sol <- function(x) { 
paste(unlist(list(gsub("\\.+$", "", x), 
    rep(" ", nchar(x) - nchar(gsub("\\.+$", "", x))))),collapse="") 
} 

sapply(x, messy.sol, USE.NAMES = FALSE) 

Yo diría que Tim es un poco más lindo :)

+0

+1, siempre y cuando funcione;) –

2

La solución de Tim es claramente mejor, pero pensé que probaría mi mano de una manera alternativa. Usando el uso liberal de regmatches nos ayuda aquí

x <- c("good", "little.bad", "really.ugly......") 
# Get an object with 'match data' to feed into regmatches 
# Here we match on any number of periods at the end of a string 
out <- regexpr("\\.*$", x) 

# On the right hand side we extract the pieces of the strings 
# that match our pattern with regmatches and then replace 
# all the periods with spaces. Then we use assignment 
# to store that into the spots in our strings that match the 
# regular expression. 
regmatches(x, out) <- gsub("\\.", " ", regmatches(x, out)) 
x 
#[1] "good"    "little.bad"  "really.ugly  " 

Así que no es tan limpia como una sola expresión regular. Pero nunca me he acostumbrado a aprender esas 'anticipaciones' en las expresiones regulares de Perl.

+0

no tan limpio como Tim, pero sigue siendo una buena solución (particularmente en comparación con el mío)) +1 –

Cuestiones relacionadas