Estas notas están basadas en los apuntes de Gloria Li y Jenny Bryan.
Una “expresión regular” es un patrón que define una cadena de texto con una particular estructura. Las expresiones regulares son muy útiles en programación en general, pero aquí las usaremos para limpiar y preparar texto. En R
hay varios paquetes que proveen de herramientas para trabajar con expresiones regulares, como stringr
. Algunas de las cosas que podemos hacer con expresiones regulares:
- identificar cadenas que encajan con un patron:
grep(..., value = FALSE)
, grepl()
, stringr::str_detect()
.
- extraer cadenas que encajan con un patrón:
grep(..., value = TRUE)
, stringr::str_extract()
, stringr::str_extract_all()
- localizar patrones dentro de una cadena.
regexpr()
, gregexpr()
, stringr::str_locate()
, string::str_locate_all()
- reemplazar cadenas dentro de un patrón:
gsub()
, stringr::str_replace()
, stringr::str_replace_all()
- separar una cadena usando un patrón:
strsplit()
, stringr::str_split()
Sintaxis de las expresiones regulares
Las expresiones regulares especifican caracteres (o clases de caracteres) para identificar repeticiones y localizaciones en cadenas de texto. Para conseguir eso, algunos símbolos tienen un significado especial, como $
, *
, (
o )
.
Escapes
Hay algunos caracteres en R
que no pueden convertirse directamente a una cadena. Por ejemplo, supongamos que especificamos un patrón que incluye una comilla para encontrar expresiones que usen el genitivo sajón. Para conseguir eso tendríamos que “escapar” la comilla, ya que una única comilla produciría un error en el intérprete de R
. Para escapar expresiones usamos \\
:
grep('\'', c("its", "it's"), value = TRUE)
Hay otros caracteres que requiren ser escapados:
\\'
: Comilla.
\"
: Doble comilla.
\n
: Nueva linea.
\r
: Retorno.
\t
: Tabulación.
Cuantificadores
Los cuantificadores permiten especificar el número de repeticiones en un patrón.
*
: El carácter puede aparecer al menos 0 veces.
+
: El carácter puede aparecer al menos 1 vez.
?
: El carácter puede aparecer hasta 1 vez.
{n}
: El carácter aparece n veces.
{n,}
: El carácter puede aparecer al menos n veces.
{n,m}
: El carácter puede aparecer entre m y n veces.
Veamos unos ejemplos:
(strings <- c("a", "ab", "acb", "accb", "acccb", "accccb"))
grep("ac*b", strings, value = TRUE)
grep("ac+b", strings, value = TRUE)
grep("ac?b", strings, value = TRUE)
grep("ac{2}b", strings, value = TRUE)
grep("ac{2,}b", strings, value = TRUE)
grep("ac{2,3}b", strings, value = TRUE)
Posiciones del patrón dentro de la cadena
También podemos encajar caracteres por posición:
^
: Principio de la cadena,
$
: Final de la cadena.
\b
: Límite de palabra.
(strings <- c("abcd", "cdab", "cabd", "c abd"))
grep("ab", strings, value = TRUE)
grep("^ab", strings, value = TRUE)
grep("ab$", strings, value = TRUE)
grep("\\bab", strings, value = TRUE)
Operadores
.
: Empareja con cualquier caracter.
[...]
: Establece una lista de caracteres.
[^...]
: El inverso de la lista de caracteres: empareja los caracteres que no estén en la lista.
\\
: Escapa metacaracteres en una expresión regular. Por ejemplo, para emparejar \.
o \[
. Nótese que \\
es en sí un caracter que necesita ser escapado, con lo que en R
usaremos \\.
o \\[
.
|
: El operador OR.
(...)
: Agrupamiento. Nos permite marcar y definir secciones dentro de la expresión. Cada uno de estos agrupamientos puede ser recuperado usando \\n
, en el que n
es el número de agrupamientos.
(strings <- c("^ab", "ab", "abc", "abd", "abe", "ab 12"))
grep("ab.", strings, value = TRUE)
grep("ab[c-e]", strings, value = TRUE)
grep("ab[^c]", strings, value = TRUE)
grep("^ab", strings, value = TRUE)
grep("\\^ab", strings, value = TRUE)
grep("abc|abd", strings, value = TRUE)
gsub("(ab) 12", "\\1 34", strings)
Clases de caracteres
La clases de caracteres nos permiten listar tipos de caracteres, como letras, números, puntuación, … Hay dos tipos de notación para clases de caracteres: una usa [:
y la otra escapa un caracter especial, como \\w
.
[:digit:]
or \d
. Dígitos del 0 al 9, equivalente a [0-9]
.
\D
: Inverso de \d
, es decir, equivalente a [^0-9]
.
[:lower:]
: Minúsculas, equivalente a [a-z]
.
[:upper:]
: Mayúsculas, equivalente a [A-Z]
[:alpha:]
: Mayúsculas y minúsculas.
[:alnum:]
: Caracteres alfanuméricos. Dígitos, mayúsculas y minúsculas. Equivalente a \w
.
\W
: Inverso de w
.
[:blank:]
: Espacio y tabulación.
[:space:]
: Espacio: tabulación, nueva línea, retorno de línea y espacio.
[:punct:]
: Puntuación.
Modos generales de patrones
R
ofrece dos sintaxis para la gestión de expresiones regulares.
POSIX
, que es activado por defecto.
Perl
El argumento perl
en funciones como grep
o gsub
nos permite cambiar entre un estilo u otro.
LS0tIAp0aXRsZTogIkV4cHJlc2lvbmVzIHJlZ3VsYXJlcyBlbiBgUmAiCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVCICVkLCAlWScpYCIKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRSwgY2FjaGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChldmFsID0gRkFMU0UpIApgYGAKCkVzdGFzIG5vdGFzIGVzdMOhbiBiYXNhZGFzIGVuIGxvcyBhcHVudGVzIGRlIFtHbG9yaWEgTGkgeSBKZW5ueSBCcnlhbl0oaHR0cDovL3N0YXQ1NDUuY29tL2Jsb2NrMDIyX3JlZ3VsYXItZXhwcmVzc2lvbi5odG1sKS4KClVuYSAiZXhwcmVzacOzbiByZWd1bGFyIiBlcyB1biBwYXRyw7NuIHF1ZSBkZWZpbmUgdW5hIGNhZGVuYSBkZSB0ZXh0byBjb24gdW5hCnBhcnRpY3VsYXIgZXN0cnVjdHVyYS4gTGFzIGV4cHJlc2lvbmVzIHJlZ3VsYXJlcyBzb24gbXV5IMO6dGlsZXMgZW4gcHJvZ3JhbWFjacOzbgplbiBnZW5lcmFsLCBwZXJvIGFxdcOtIGxhcyB1c2FyZW1vcyBwYXJhIGxpbXBpYXIgeSBwcmVwYXJhciB0ZXh0by4gRW4gYFJgIGhheQp2YXJpb3MgcGFxdWV0ZXMgcXVlIHByb3ZlZW4gZGUgaGVycmFtaWVudGFzIHBhcmEgdHJhYmFqYXIgY29uIGV4cHJlc2lvbmVzCnJlZ3VsYXJlcywgY29tbyBgc3RyaW5ncmAuIEFsZ3VuYXMgZGUgbGFzIGNvc2FzIHF1ZSBwb2RlbW9zIGhhY2VyIGNvbgpleHByZXNpb25lcyByZWd1bGFyZXM6CgotIGlkZW50aWZpY2FyIGNhZGVuYXMgcXVlIGVuY2FqYW4gY29uIHVuIHBhdHJvbjogYGdyZXAoLi4uLCB2YWx1ZSA9IEZBTFNFKWAsIGBncmVwbCgpYCwKICAgYHN0cmluZ3I6OnN0cl9kZXRlY3QoKWAuCi0gZXh0cmFlciBjYWRlbmFzIHF1ZSBlbmNhamFuIGNvbiB1biBwYXRyw7NuOiBgZ3JlcCguLi4sIHZhbHVlID0gVFJVRSlgLAogICBgc3RyaW5ncjo6c3RyX2V4dHJhY3QoKWAsIGBzdHJpbmdyOjpzdHJfZXh0cmFjdF9hbGwoKWAKLSBsb2NhbGl6YXIgcGF0cm9uZXMgZGVudHJvIGRlIHVuYSBjYWRlbmEuIGByZWdleHByKClgLCBgZ3JlZ2V4cHIoKWAsCiAgIGBzdHJpbmdyOjpzdHJfbG9jYXRlKClgLCBgc3RyaW5nOjpzdHJfbG9jYXRlX2FsbCgpYAotIHJlZW1wbGF6YXIgY2FkZW5hcyBkZW50cm8gZGUgdW4gcGF0csOzbjogYGdzdWIoKWAsIGBzdHJpbmdyOjpzdHJfcmVwbGFjZSgpYCwKICAgYHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbCgpYAotIHNlcGFyYXIgdW5hIGNhZGVuYSB1c2FuZG8gdW4gcGF0csOzbjogYHN0cnNwbGl0KClgLCBgc3RyaW5ncjo6c3RyX3NwbGl0KClgCgojIyBTaW50YXhpcyBkZSBsYXMgZXhwcmVzaW9uZXMgcmVndWxhcmVzCgpMYXMgZXhwcmVzaW9uZXMgcmVndWxhcmVzIGVzcGVjaWZpY2FuIGNhcmFjdGVyZXMgKG8gY2xhc2VzIGRlIGNhcmFjdGVyZXMpIHBhcmEKaWRlbnRpZmljYXIgcmVwZXRpY2lvbmVzIHkgbG9jYWxpemFjaW9uZXMgZW4gY2FkZW5hcyBkZSB0ZXh0by4gUGFyYSBjb25zZWd1aXIKZXNvLCBhbGd1bm9zIHPDrW1ib2xvcyB0aWVuZW4gdW4gc2lnbmlmaWNhZG8gZXNwZWNpYWwsIGNvbW8gYCRgLCBgKmAsIGAoYCBvIGApYC4KCiMjIEVzY2FwZXMKCkhheSBhbGd1bm9zIGNhcmFjdGVyZXMgZW4gYFJgIHF1ZSBubyBwdWVkZW4gY29udmVydGlyc2UgZGlyZWN0YW1lbnRlIGEgdW5hCmNhZGVuYS4gUG9yIGVqZW1wbG8sIHN1cG9uZ2Ftb3MgcXVlIGVzcGVjaWZpY2Ftb3MgdW4gcGF0csOzbiBxdWUgaW5jbHV5ZSB1bmEKY29taWxsYSBwYXJhIGVuY29udHJhciBleHByZXNpb25lcyBxdWUgdXNlbiBlbCBnZW5pdGl2byBzYWrDs24uICBQYXJhIGNvbnNlZ3Vpcgplc28gdGVuZHLDrWFtb3MgcXVlICJlc2NhcGFyIiBsYSBjb21pbGxhLCB5YSBxdWUgdW5hIMO6bmljYSBjb21pbGxhIHByb2R1Y2lyw61hIHVuCmVycm9yIGVuIGVsIGludMOpcnByZXRlIGRlIGBSYC4gUGFyYSBfZXNjYXBhcl8gZXhwcmVzaW9uZXMgdXNhbW9zIGBcXGA6CgpgYGB7cn0KZ3JlcCgnXCcnLCBjKCJpdHMiLCAiaXQncyIpLCB2YWx1ZSA9IFRSVUUpCmBgYAoKSGF5IG90cm9zIGNhcmFjdGVyZXMgcXVlIHJlcXVpcmVuIHNlciBlc2NhcGFkb3M6CgotIGBcXCdgOiBDb21pbGxhLgotIGBcImA6IERvYmxlIGNvbWlsbGEuIAotIGBcbmA6IE51ZXZhIGxpbmVhLgotIGBccmA6IFJldG9ybm8uCi0gYFx0YDogVGFidWxhY2nDs24uCgoKIyMgQ3VhbnRpZmljYWRvcmVzCgpMb3MgY3VhbnRpZmljYWRvcmVzIHBlcm1pdGVuIGVzcGVjaWZpY2FyIGVsIG7Dum1lcm8gZGUgcmVwZXRpY2lvbmVzIGVuIHVuIHBhdHLDs24uCgotIGAqYDogRWwgY2Fyw6FjdGVyIHB1ZWRlIGFwYXJlY2VyIGFsIG1lbm9zIDAgdmVjZXMuCi0gYCtgOiBFbCBjYXLDoWN0ZXIgcHVlZGUgYXBhcmVjZXIgYWwgbWVub3MgMSB2ZXouCi0gYD9gOiBFbCBjYXLDoWN0ZXIgcHVlZGUgYXBhcmVjZXIgaGFzdGEgMSB2ZXouCi0gYHtufWA6IEVsIGNhcsOhY3RlciBhcGFyZWNlIG4gdmVjZXMuCi0gYHtuLH1gOiBFbCBjYXLDoWN0ZXIgcHVlZGUgYXBhcmVjZXIgYWwgbWVub3MgbiB2ZWNlcy4KLSBge24sbX1gOiBFbCBjYXLDoWN0ZXIgcHVlZGUgYXBhcmVjZXIgZW50cmUgbSB5IG4gdmVjZXMuCgpWZWFtb3MgdW5vcyBlamVtcGxvczoKCmBgYHtyfQooc3RyaW5ncyA8LSBjKCJhIiwgImFiIiwgImFjYiIsICJhY2NiIiwgImFjY2NiIiwgImFjY2NjYiIpKQpgYGAKCmBgYHtyfQpncmVwKCJhYypiIiwgc3RyaW5ncywgdmFsdWUgPSBUUlVFKQpgYGAKCmBgYHtyfQpncmVwKCJhYytiIiwgc3RyaW5ncywgdmFsdWUgPSBUUlVFKQpgYGAKCmBgYHtyfQpncmVwKCJhYz9iIiwgc3RyaW5ncywgdmFsdWUgPSBUUlVFKQpgYGAKCmBgYHtyfQpncmVwKCJhY3syfWIiLCBzdHJpbmdzLCB2YWx1ZSA9IFRSVUUpCmBgYAoKYGBge3J9CmdyZXAoImFjezIsfWIiLCBzdHJpbmdzLCB2YWx1ZSA9IFRSVUUpCmBgYAoKYGBge3J9CmdyZXAoImFjezIsM31iIiwgc3RyaW5ncywgdmFsdWUgPSBUUlVFKQpgYGAKCiMjIFBvc2ljaW9uZXMgZGVsIHBhdHLDs24gZGVudHJvIGRlIGxhIGNhZGVuYQoKVGFtYmnDqW4gcG9kZW1vcyBlbmNhamFyIGNhcmFjdGVyZXMgcG9yIHBvc2ljacOzbjoKCi0gYF5gOiBQcmluY2lwaW8gZGUgbGEgY2FkZW5hLAotIGAkYDogRmluYWwgZGUgbGEgY2FkZW5hLgotIGBcYmA6IEzDrW1pdGUgZGUgcGFsYWJyYS4KCmBgYHtyfQooc3RyaW5ncyA8LSBjKCJhYmNkIiwgImNkYWIiLCAiY2FiZCIsICJjIGFiZCIpKQpgYGAKCmBgYHtyfQpncmVwKCJhYiIsIHN0cmluZ3MsIHZhbHVlID0gVFJVRSkKYGBgCgpgYGB7cn0KZ3JlcCgiXmFiIiwgc3RyaW5ncywgdmFsdWUgPSBUUlVFKQpgYGAKCmBgYHtyfQpncmVwKCJhYiQiLCBzdHJpbmdzLCB2YWx1ZSA9IFRSVUUpCmBgYAoKYGBge3J9CmdyZXAoIlxcYmFiIiwgc3RyaW5ncywgdmFsdWUgPSBUUlVFKQpgYGAKCgojIyBPcGVyYWRvcmVzCgotIGAuYDogRW1wYXJlamEgY29uIGN1YWxxdWllciBjYXJhY3Rlci4KLSBgWy4uLl1gOiBFc3RhYmxlY2UgdW5hIGxpc3RhIGRlIGNhcmFjdGVyZXMuIAotIGBbXi4uLl1gOiBFbCBpbnZlcnNvIGRlIGxhIGxpc3RhIGRlIGNhcmFjdGVyZXM6IGVtcGFyZWphIGxvcyBjYXJhY3RlcmVzIHF1ZQogIF9ub18gZXN0w6luIGVuIGxhIGxpc3RhLgotIGBcXGA6IEVzY2FwYSBtZXRhY2FyYWN0ZXJlcyBlbiB1bmEgZXhwcmVzacOzbiByZWd1bGFyLiBQb3IgZWplbXBsbywgcGFyYQogIGVtcGFyZWphciBgXC5gIG8gYFxbYC4gTsOzdGVzZSBxdWUgYFxcYCBlcyBlbiBzw60gdW4gY2FyYWN0ZXIgcXVlICBuZWNlc2l0YSBzZXIKICBlc2NhcGFkbywgY29uIGxvIHF1ZSBlbiBgUmAgdXNhcmVtb3MgYFxcLmAgbyBgXFxbYC4KLSBgfGA6IEVsIG9wZXJhZG9yIE9SLgotIGAoLi4uKWA6IEFncnVwYW1pZW50by4gTm9zIHBlcm1pdGUgbWFyY2FyIHkgZGVmaW5pciBzZWNjaW9uZXMgZGVudHJvIGRlIGxhCiAgZXhwcmVzacOzbi4gQ2FkYSB1bm8gZGUgZXN0b3MgYWdydXBhbWllbnRvcyBwdWVkZSBzZXIgcmVjdXBlcmFkbyB1c2FuZG8gYFxcbmAsCiAgZW4gZWwgcXVlIGBuYCBlcyBlbCBuw7ptZXJvIGRlIGFncnVwYW1pZW50b3MuCgpgYGB7cn0KKHN0cmluZ3MgPC0gYygiXmFiIiwgImFiIiwgImFiYyIsICJhYmQiLCAiYWJlIiwgImFiIDEyIikpCmBgYAoKYGBge3J9CmdyZXAoImFiLiIsIHN0cmluZ3MsIHZhbHVlID0gVFJVRSkKYGBgCgpgYGB7cn0KZ3JlcCgiYWJbYy1lXSIsIHN0cmluZ3MsIHZhbHVlID0gVFJVRSkKYGBgCgpgYGB7cn0KZ3JlcCgiYWJbXmNdIiwgc3RyaW5ncywgdmFsdWUgPSBUUlVFKQpgYGAKCmBgYHtyfQpncmVwKCJeYWIiLCBzdHJpbmdzLCB2YWx1ZSA9IFRSVUUpCmBgYAoKYGBge3J9CmdyZXAoIlxcXmFiIiwgc3RyaW5ncywgdmFsdWUgPSBUUlVFKQpgYGAKCmBgYHtyfQpncmVwKCJhYmN8YWJkIiwgc3RyaW5ncywgdmFsdWUgPSBUUlVFKQpgYGAKCmBgYHtyfQpnc3ViKCIoYWIpIDEyIiwgIlxcMSAzNCIsIHN0cmluZ3MpCmBgYAoKIyMgQ2xhc2VzIGRlIGNhcmFjdGVyZXMKCkxhIGNsYXNlcyBkZSBjYXJhY3RlcmVzIG5vcyBwZXJtaXRlbiBsaXN0YXIgdGlwb3MgZGUgY2FyYWN0ZXJlcywgY29tbyBsZXRyYXMsCm7Dum1lcm9zLCBwdW50dWFjacOzbiwgLi4uIEhheSBkb3MgdGlwb3MgZGUgbm90YWNpw7NuIHBhcmEgY2xhc2VzIGRlIGNhcmFjdGVyZXM6CnVuYSB1c2EgYFs6YCB5IGxhIG90cmEgZXNjYXBhIHVuIGNhcmFjdGVyIGVzcGVjaWFsLCBjb21vIGBcXHdgLgoKLSBgWzpkaWdpdDpdYCBvciBgXGRgLiBEw61naXRvcyBkZWwgMCBhbCA5LCBlcXVpdmFsZW50ZSBhIGBbMC05XWAuCi0gYFxEYDogSW52ZXJzbyBkZSBgXGRgLCBlcyBkZWNpciwgZXF1aXZhbGVudGUgYSBgW14wLTldYC4KLSBgWzpsb3dlcjpdYDogTWluw7pzY3VsYXMsIGVxdWl2YWxlbnRlIGEgYFthLXpdYC4KLSBgWzp1cHBlcjpdYDogTWF5w7pzY3VsYXMsIGVxdWl2YWxlbnRlIGEgYFtBLVpdYAotIGBbOmFscGhhOl1gOiBNYXnDunNjdWxhcyB5IG1pbsO6c2N1bGFzLgotIGBbOmFsbnVtOl1gOiBDYXJhY3RlcmVzIGFsZmFudW3DqXJpY29zLiBEw61naXRvcywgbWF5w7pzY3VsYXMgeSBtaW7DunNjdWxhcy4KICBFcXVpdmFsZW50ZSBhIGBcd2AuIAotIGBcV2A6IEludmVyc28gZGUgYHdgLgotIGBbOmJsYW5rOl1gOiBFc3BhY2lvIHkgdGFidWxhY2nDs24uCi0gYFs6c3BhY2U6XWA6IEVzcGFjaW86IHRhYnVsYWNpw7NuLCBudWV2YSBsw61uZWEsIHJldG9ybm8gZGUgbMOtbmVhIHkgZXNwYWNpby4KLSBgWzpwdW5jdDpdYDogUHVudHVhY2nDs24uCgojIyBNb2RvcyBnZW5lcmFsZXMgZGUgcGF0cm9uZXMKCmBSYCBvZnJlY2UgZG9zIHNpbnRheGlzIHBhcmEgbGEgZ2VzdGnDs24gZGUgZXhwcmVzaW9uZXMgcmVndWxhcmVzLgoKLSBgUE9TSVhgLCBxdWUgZXMgYWN0aXZhZG8gcG9yIGRlZmVjdG8uCi0gYFBlcmxgCgpFbCBhcmd1bWVudG8gYHBlcmxgIGVuIGZ1bmNpb25lcyBjb21vIGBncmVwYCBvIGBnc3ViYCBub3MgcGVybWl0ZSBjYW1iaWFyIGVudHJlCnVuIGVzdGlsbyB1IG90cm8uCg==