2012-01-02 21 views
23

Me gustaría utilizar el gsub de R para eliminar toda la puntuación de un texto, excepto los apóstrofos. Soy bastante nuevo en Regex, pero estoy aprendiendo.Eliminar toda la puntuación excepto los apóstrofes en R

Ejemplo:

x <- "I like %[email protected]*&, chew;: gum, but don't like|}{[] [email protected]#^)(gum!?" 
gsub("[[:punct:]]", "", as.character(x)) 

Corriente de salida (sin apóstrofe en hacerlo no)

[1] "I like to chew gum but dont like bubble gum" 

salida deseada (deseo del apóstrofe en no quedarse)

[1] "I like to chew gum but don't like bubble gum" 

Respuesta

31
x <- "I like %[email protected]*&, chew;: gum, but don't like|}{[] [email protected]#^)(gum!?" 
gsub("[^[:alnum:][:space:]']", "", x) 

[1] "I like to chew gum but don't like bubble gum" 

la expresión regular anterior es mucho más sencillo. Reemplaza todo lo que no sea signos alfanuméricos, espacio o apóstrofo (símbolo de intercalación) con una cadena vacía.

+0

Kay su código elimina el apóstrofo. Esto es lo que creo que quiso decir 'gsub (" [^ [: alnum:] [: espacio:] '\ "]", "", x) ' –

+0

Me gusta lo fácil que es esta codificación. –

+2

+1 - La idea aquí apunta a ser la solución más clara posible, en mi opinión. Solo edite la segunda línea para leer 'gsub (" [^ [: alnum:] [: espacio:] '] "," ", x)' y es dorado. (FWIW, la barra invertida no es necesaria dentro de la expresión regular). –

6

Aquí se muestra un ejemplo:

> gsub("(.*?)($|'|[^[:punct:]]+?)(.*?)", "\\2", x) 
[1] "I like to chew gum but don't like bubble gum" 
+0

Exactamente lo que esperaba. Mucho más complicado de lo que pensé que sería. No me extraña que tuviera problemas. Realmente desarmaré lo que hiciste. Gracias. –

+1

Finalmente, esta sería la forma más simple 'gsub (". *? ($ | '| [^ [: Punct:]]). *? "," \\ 1 ", x)'. – kohske

+0

Gracias por el seguimiento. Funciona tan bien como el primero y es más simple de seguir. +1 –

4

Sobre todo para la variedad, he aquí una solución utilizando gsubfn() del maravilloso paquete del mismo nombre. En esta solicitud, al igual que lo bien expresiva la solución que permite es:.

library(gsubfn) 
gsubfn(pattern = "[[:punct:]]", engine = "R", 
     replacement = function(x) ifelse(x == "'", "'", ""), 
     x) 
[1] "I like to chew gum but don't like bubble gum" 

(El argumento se necesita engine = "R" aquí como en caso contrario se utiliza el motor TCL predeterminado Sus reglas para hacer coincidir expresiones regulares son ligeramente diferentes: si se utiliza para procesar la cadena anterior, por ejemplo, habría que fijar en su lugar pattern = "[[:punct:]$|^]". Gracias a G. Grothendieck por señalar ese detalle.)

+2

Una advertencia: por alguna razón, la clase de caracteres '[: punct:]', cuando se utiliza en el argumento 'pattern' de una llamada' gsubfn() ', no coincide con los caracteres' $ ',' | ', o'^'como lo haría en una llamada a' gsub() '. Así que tuve que agregarlos 'a mano'. –

+2

'gsubfn' usa la expresión regular tcl de forma predeterminada. Usa el argumento 'engine =" R "' si deseas usar R expresiones regulares. –

+0

@ G.Grothendieck - Gracias por señalarlo. Lo he incorporado en mi respuesta. Había tomado la documentación en '? Gsubfn', que establece que' patrón: igual que 'patrón' en 'gsub'', para indicar que los patrones deberían especificarse de la misma manera. Ahora veo lo que se quiso decir con eso, pero me pregunto si una línea adicional podría ayudar. Algo así como 'Si engine =" R ", las cadenas de caracteres se emparejarán según lo documentado por 'help (regex)'. Si se utiliza el motor tcl predeterminado, los patrones se ajustarán según lo documentado en ... '.En cualquier caso, ¡gracias por tu trabajo en el paquete! –

2

Puede excluir apóstrofes de la clase POSIX punct utilizando una doble negación:

[^'[:^punct:]] 

Código:

x <- "I like %[email protected]*&, chew;: gum, but don't like|}{[] [email protected]#^)(gum!?" 
gsub("[^'[:^punct:]]", "", x, perl=T) 

#[1] "I like to chew gum but don't like bubble gum" 

ideone demo

Cuestiones relacionadas