Saltar al contenido principal
InicioTutorialesProgramación R

Guía de expresiones regulares en R

Explore las expresiones regulares en R, por qué son importantes, las herramientas y funciones para trabajar con ellas, patrones regex comunes y cómo utilizarlos.
may 2024  · 16 min leer

El concepto de expresiones regulares, normalmente denominado regex, existe en muchos lenguajes de programación, como R, Python, C, C++, Perl, Java y JavaScript. Puede acceder a la funcionalidad de regex en la versión base de esos lenguajes o a través de bibliotecas. En la mayoría de los lenguajes de programación, la sintaxis de los patrones regex es similar.

En este tutorial, exploraremos qué son las expresiones regulares en R, por qué son importantes, qué herramientas y funciones nos permiten trabajar con ellas, qué patrones regex son los más comunes y cómo utilizarlos. Al final, repasaremos algunas aplicaciones avanzadas de R regex.

¿Qué son las expresiones regulares en R y por qué hay que utilizarlas?

Una expresión regular, regex, en R es una secuencia de caracteres (o incluso un carácter) que describe un determinado patrón encontrado en un texto. Los patrones Regex pueden ser tan cortos como 'a' o tan largos como el mencionado en este hilo de StackOverflow.

En términos generales, la definición anterior de regex está relacionada no sólo con R, sino también con cualquier otro lenguaje de programación que admita expresiones regulares.

Regex representa una herramienta muy flexible y potente ampliamente utilizada para el procesamiento y la minería de datos de texto no estructurados. Por ejemplo, encuentran su aplicación en motores de búsqueda, análisis léxico, filtrado de spam y editores de texto.

Herramientas y funciones para trabajar con R Regex

Aunque los patrones regex son similares para la mayoría de los lenguajes de programación, las funciones para trabajar con ellos son diferentes.

En R, podemos utilizar las funciones de la base R para detectar, hacer coincidir, localizar, extraer y reemplazar regex. A continuación se muestran las principales funciones que buscan coincidencias regex en un vector de caracteres y luego hacen lo siguiente:

  • grep(), grepl() - devuelven los índices de las cadenas que contienen una coincidencia (grep() ) o un vector lógico que muestra qué cadenas contienen una coincidencia (grepl()).
  • regexpr(), gregexpr() - devuelven el índice de cada cadena donde comienza la coincidencia y la longitud de dicha coincidencia. Mientras que regexpr() proporciona esta información sólo para la primera coincidencia (desde la izquierda), gregexpr() hace lo mismo para todas las coincidencias.
  • sub(), gsub() - sustituyen una coincidencia detectada en cada cadena por una cadena especificada (sub() - sólo para la primera coincidencia, gsub() - para todas las coincidencias).
  • regexec() - funciona como regexpr() pero devuelve la misma información también para una subexpresión especificada dentro de la coincidencia.
  • regmatches() - funciona como regexec() pero devuelve las cadenas exactas detectadas para la coincidencia global y una subexpresión especificada.

Sin embargo, en lugar de utilizar las funciones nativas de R, una forma más cómoda y consistente de trabajar con R regex es utilizar un paquete especializado stringr de la colección tidyverse. Esta biblioteca se basa en el paquete stringi. En la biblioteca stringr, todas las funciones empiezan por str_ y tienen nombres mucho más intuitivos (así como los nombres de sus parámetros opcionales) que los de la base R.

Para instalar y cargar el paquete stringr, ejecute lo siguiente:

install.packages('stringr')
library(stringr)

La siguiente tabla muestra la correspondencia entre las funciones stringr y las de la base R que hemos discutido anteriormente en esta sección:

stringr

Base R

str_subset()

grep()

str_detect()

grepl()

str_extract()

regexpr(), regmatches(), grep()

str_match()

regexec()

str_locate()

regexpr()

str_locate_all()

gregexpr()

str_replace()

sub()

str_replace_all()

gsub()

Puedes encontrar una lista completa de las funciones stringr y expresiones regulares en estas hojas de trucos, pero discutiremos algunas de ellas más adelante en este tutorial.

Nota: en las funciones stringr, pasamos primero los datos y luego una regex, mientras que en las funciones base de R - justo lo contrario.

R Regex Patterns

Ahora, vamos a repasar los patrones regex más populares de R y su uso y, al mismo tiempo, practicaremos algunas de las funciones stringr.

Antes de hacerlo, veamos un ejemplo muy básico. En concreto, comprobemos si un unicornio tiene al menos un maíz 😉

str_detect('unicorn', 'corn')

Salida:

TRUE

En este ejemplo, hemos utilizado la función str_detect() stringr para comprobar la presencia de la cadena corn en la cadena unicornio.

Sin embargo, normalmente no buscamos una cadena literal determinada en un fragmento de texto, sino más bien un patrón determinado: una expresión regular. Sumerjámonos en la exploración de estos patrones.

Escapadas de personajes

Hay algunos caracteres que tienen un significado especial cuando se utilizan en expresiones regulares de R. Más concretamente, no coinciden entre sí, como todas las letras y dígitos, sino que hacen algo diferente:

str_extract_all('unicorn', '.')

Salida:

1. 'u' 'n' 'i' 'c' 'o' 'r' 'n'

Vemos claramente que no hay puntos en nuestro unicornio. Sin embargo, la función str_extract_all( ) extrajo todos y cada uno de los caracteres de esta cadena. Esta es la misión exacta del carácter .: coincidir con cualquier carácter, excepto con una nueva línea.

¿Y si queremos extraer un punto literal? Para ello, tenemos que utilizar un carácter de escape regex antes del punto - una barra invertida (\). Sin embargo, hay que tener en cuenta una trampa: la barra invertida también se utiliza en las propias cadenas como carácter de escape. Esto significa que primero tenemos que "escapar del carácter de escape", utilizando una doble barra invertida. Veamos cómo funciona:

str_extract_all('Eat. Pray. Love.', '\\.')

Salida:

1. '.' '.' '.'

Por lo tanto, la barra invertida ayuda a ignorar el significado especial de algunos símbolos en las expresiones regulares de R e interpretarlos literalmente. También tiene la misión contraria: dar un significado especial a algunos caracteres que de otro modo se interpretarían literalmente. A continuación se muestra una tabla con las secuencias de escape de caracteres más utilizadas:

R regex

Qué coincide

\b

Un límite de palabra (un límite entre una \w y una \W)

\B

Un límite no verbal(\w-\w o \W-\W)

\n

Una nueva línea

\t

Una ficha

\v

Una pestaña vertical

Veamos algunos ejemplos teniendo en cuenta que también en estos casos debemos utilizar una doble barra invertida. Al mismo tiempo, introduciremos dos funciones stringr más: str_view() y str_view_all() (para ver la representación HTML de la primera coincidencia o de todas las coincidencias):

str_view('Unicorns are so cute!', 's\\b')
str_view('Unicorns are so cute!', 's\\B')

Salida:

¡Los unicornios son tan monos!

¡Los unicornios son tanmonos!

En la cadena ¡Los unicornios son tan monos!, hay dos instancias de la letra s. Arriba, el primer patrón regex R resaltó la primera instancia de la letra s (ya que va seguida de un espacio), mientras que el segundo - la segunda instancia (ya que va seguida de otra letra, no de un límite de palabra).

Un par de ejemplos más:

cat('Unicorns are\nso cute!')
str_view_all('Unicorns are\nso cute!', '\\n')

Salida:

Unicorns are
so cute!

¡Los unicornios son tanmonos!

cat('Unicorns are\tso cute!')
str_view_all('Unicorns are\tso cute!', '\\t')

Salida:

Unicorns are so    cute!

¡Los unicornios son tanmonos!

Clases de personajes

Una clase de caracteres coincide con cualquier carácter de un conjunto predefinido de caracteres. Las clases de caracteres incorporadas tienen la misma sintaxis que las secuencias de escape de caracteres que vimos en la sección anterior: una barra invertida seguida de una letra a la que da un significado especial en lugar de su significado literal. A continuación se presentan las construcciones más populares:

R regex

Qué coincide

\w

Cualquier carácter de palabra (cualquier letra, dígito o guión bajo)

\W

Cualquier carácter que no sea una palabra

\d

Cualquier dígito

\D

Cualquier cifra no numérica

\s

Cualquier carácter de espacio (un espacio, un tabulador, una nueva línea, etc.)

\S

Cualquier carácter que no sea un espacio

Veamos algunos ejemplos que se explican por sí solos:

str_view_all('Unicorns are so cute!', '\\w')
str_view_all('Unicorns are so cute!', '\\W')

Salida:

¡Los unicornios son tan monos!

¡Los unicornios son tanmonos!

str_view_all('Unicorns are\nso cute!', '\\s')
str_view_all('Unicorns are\nso cute!', '\\S')

Salida:

¡Los unicornios son tanmonos!

Unicornios son tan ¡lindos!

str_detect('Unicorns are so cute!', '\\d')

Salida:

FALSE

Las clases de caracteres incorporadas también pueden aparecer de forma alternativa - [:nombre_clase_carácter:]. Algunas de estas clases de caracteres tienen un equivalente entre las que llevan barra invertida, otras no. Las más comunes son:

R regex

Qué coincide

[:alpha:]

Cualquier letra

[:lower:]

Cualquier letra minúscula

[:upper:]

Cualquier letra mayúscula

[:digit:]

Cualquier dígito (equivalente a \d)

[:alnum:]

Cualquier letra o número

[:xdigit:]

Cualquier dígito hexadecimal

[:punct:]

Cualquier signo de puntuación

[:gráfico:]

Cualquier letra, número o signo de puntuación

[:espacio:]

Un espacio, un tabulador, una nueva línea, etc. (equivalente a \s)

Exploremos algunos ejemplos teniendo en cuenta que tenemos que poner cualquiera de los patrones regex R anteriores dentro de corchetes:

str_view('Unicorns are so cute!', '[[:upper:]]')
str_view('Unicorns are so cute!', '[[:lower:]]')

Salida:

¡Los unicorniosson tan monos!

¡Los unicorniosson tan monos!

str_detect('Unicorns are so cute!', '[[:digit:]]')

Salida:

FALSE
str_extract_all('Unicorns are so cute!', '[[:punct:]]')

Salida:

1. '!'
str_view_all('Unicorns are so cute!', '[[:space:]]')

Salida:

¡Los unicornios son tanmonos!

También es posible crear una clase de caracteres definida por el usuario poniendo entre corchetes cualquier conjunto de caracteres del que queramos que coincida un carácter cualquiera. Podemos encerrar entre corchetes un rango de letras o números (en orden Unicode), varios rangos diferentes, o cualquier conjunto secuencial o no secuencial de caracteres o grupos de caracteres.

Por ejemplo, [A-D] coincidirá con cualquier letra mayúscula de la A a la D inclusive, [k-r ] - cualquier letra minúscula de la k a la r inclusive,[0-7 ] - cualquier dígito de 0 a 7 inclusive, y [aou14%9 ] - cualquiera de los caracteres indicados entre corchetes. Si colocamos el signo de intercalación (^) como primer carácter entre corchetes, nuestro patrón regex de R coincidirá con todo menos con los caracteres proporcionados. Tenga en cuenta que estos mecanismos distinguen entre mayúsculas y minúsculas.

str_view_all('Unicorns Are SOOO Cute!', '[O-V]')
str_view_all('Unicorns Are SOOO Cute!', '[^O-V]')

Salida:

¡Los unicorniosson TAN monos!

¡Los unicornios son TAN monos!

str_view_all('3.14159265359', '[0-2]')

Salida:

3.14159265359

str_view_all('The number pi is equal to 3.14159265359', '[n2e9&]')

Salida:

Elnúmeropi es iguala 3.14159265359

Cuantificadores

A menudo, necesitamos que un determinado patrón R regex coincida repetidamente, en lugar de estrictamente una vez. Para ello, utilizamos cuantificadores. Un cuantificador siempre va después del patrón regex con el que está relacionado. Los cuantificadores más comunes se indican en la tabla siguiente:

R regex

Número de repeticiones del patrón

*

0 o más

+

al menos 1

?

como máximo 1

{n}

exactamente n

{n,}

al menos n

{n,m}

como mínimo n y como máximo m

Vamos a probarlos todos:

str_extract('dog', 'dog\\d*')

Salida:

'dog'

Tenemos el perro de la cadena inicial: no hay dígitos al final de esa cadena, pero nos parece bien (0 o más instancias de dígitos).

str_extract('12345', '\\d+')

Salida:

'12345'
str_extract('12345', '\\d?')

Salida:

'1'
str_extract('12345', '\\d{3}')

Salida:

'123'
str_extract('12345', '\\d{7,}')

Salida:

NA

Tenemos NA porque no tenemos al menos 7 dígitos en la cadena, sólo 5 de ellos.

str_extract('12345', '\\d{2,4}')

Salida:

'1234'

Anclas

Por defecto, R regex coincidirá con cualquier parte de una cadena proporcionada. Podemos cambiar este comportamiento especificando una posición determinada de un patrón regex R dentro de la cadena. Lo más frecuente es que queramos imponer la coincidencia desde el principio o el final de la cadena. Para ello, utilizamos las dos anclas principales de las expresiones regulares de R:

  • ^ - coincide desde el principio de la cadena (para cadenas multilínea - el principio de cada línea)
  • $ - coincide desde el final de la cadena (para cadenas multilínea - el final de cada línea)

Veamos cómo funcionan en el ejemplo de un palíndromo stella no ganó carteras:

str_view('stella won no wallets', '^s')
str_view('stella won no wallets', 's$')

Salida:

stellano ganó carteras

stella no ganó carteras

Si queremos que coincidan los propios caracteres ^ o $, tenemos que preceder el carácter de interés con una barra invertida(duplicándola):

str_view_all('Do not have 100$, have 100 friends', '\\$')

Salida:

No tengas 100$, ten 100 amigos

También es posible anclar las coincidencias a los límites de palabra o no palabra dentro de la cadena(\b y \B respectivamente):

str_view_all('road cocoa oasis oak boa coach', '\\boa')
str_view_all('road cocoa oasis oak boa coach', 'oa\\b')
str_view_all('road cocoa oasis oak boa coach', 'oa\\B')

Salida:

carretera cacao oasis robleboa entrenador

carreteracacao oasis robleboa entrenador

carreteracacao oasis robleboaentrenador

Arriba, emparejamos la combinación de letras oa:

  • 1er ejemplo - al principio de las palabras
  • 2º ejemplo - al final de las palabras
  • 3er ejemplo - siempre que vaya seguido de un carácter de palabra (en nuestro caso - de una letra)

Alternancia

Aplicando el operador de alternancia(|), podemos hacer coincidir más de un patrón regex R en la misma cadena. Tenga en cuenta que si utilizamos este operador como parte de una clase de caracteres definida por el usuario, se interpreta literalmente, por lo que no realiza ninguna alternancia.

str_view_all('coach koala board oak cocoa road boa load coat oasis boat', 'boa|coa')

Salida:

coachkoala tablaroblecacao carretera boa carga abrigooasis barco

En el ejemplo anterior, hemos emparejado todas las instancias de boa o coa.

Agrupación

Los patrones regex de R siguen ciertas reglas de precedencia. Por ejemplo, la repetición (mediante cuantificadores) tiene prioridad sobre el anclaje, mientras que el anclaje tiene prioridad sobre la alternancia. Para anular estas reglas y aumentar la precedencia de una determinada operación, debemos utilizar la agrupación. Esto puede realizarse encerrando una subexpresión de interés entre corchetes.

La agrupación funciona mejor en combinación con el operador de alternancia. Los ejemplos siguientes demuestran claramente el efecto de esta combinación:

str_view_all('code rat coat cot cat', 'co|at')
str_view_all('code rat coat cot cat', 'c(o|a)t')

Salida:

códigorata abrigo cunagato

código rata abrigo cuna gato

Aplicaciones avanzadas de las expresiones regulares de R

Todo lo que hemos discutido hasta ahora nos da una buena base para empezar a trabajar con expresiones regulares en R. Sin embargo, hay muchas más cosas que podemos hacer con esta poderosa herramienta. Sin entrar en detalles, vamos a mencionar algunas operaciones avanzadas que podemos realizar con R regex:

  • Anulación de los valores por defecto de las funciones stringr
  • Agrupaciones de grafemas
  • Referencia a grupos
  • Propiedades Unicode coincidentes
  • Aplicación del escape de caracteres avanzado
  • Comprobación de la existencia de un patrón sin incluirlo en la salida (los llamados lookarounds)
  • Hacer que el mecanismo de repetición de patrones sea perezoso en lugar de codicioso
  • Trabajar con grupos atómicos

Aprenda más en nuestro curso Expresiones regulares intermedias en R.

Reto Regex

Ahora te toca a ti practicar los patrones regex de R de los que hemos hablado en este tutorial. Para ello, utilice nuestro conjunto de datos : Internet News and Consumer Engagement, e intenta hacer lo siguiente: extrae los dominios de nivel superior (TLD) de todas las URL. Algunos ejemplos de TLD son com, net, uk, etc.

Hay más de un enfoque para completar esta tarea, incluyendo soluciones elegantes y compactas de una sola línea (pista: puedes aprender más sobre lookarounds en R regex mencionados en la sección anterior y utilizarlos para resolver este problema). Considere la siguiente guía muy poco precisa para un enfoque relativamente "novato":

  • Inspeccione algunas URL del conjunto de datos y observe qué patrones están siempre presentes en cualquier URL antes del TLD y cuáles son opcionales.
  • Observe si hay algún patrón obligatorio en cualquier URL después del TLD (y en caso afirmativo, cuáles) y qué patrones son opcionales
  • Eliminar todo lo que precede al TLD de la URL
  • Eliminar todo lo que aparece después del TLD de la URL

Para resolver el problema utilizando el algoritmo anterior, no necesitas hacer ni aprender nada adicional. Sólo tienes que refrescar todo lo que hemos tratado en este tutorial y poner en práctica tus conocimientos. En particular, necesitará las funciones stringr, los escapes de caracteres, las clases de caracteres, los cuantificadores y la agrupación.

Bonificación: Desafío nº 2

Si quieres practicar más, esta vez sin pistas, intenta hacer lo siguiente: utilizando el mismo conjunto de datos del reto anterior, extrae los nombres de dominio de todas las URL. Un ejemplo de nombre de dominio es google en la URL www.google.com.

Conclusión

Para concluir, en este tutorial hemos aprendido muchas cosas sobre las expresiones regulares de R. En particular, debatimos:

  • Qué son las expresiones regulares en R
  • Por qué son importantes y dónde se aplican
  • Qué funciones (tanto de R nativo como de una biblioteca especializada) se utilizan para trabajar con expresiones regulares de R.
  • Los patrones regex más comunes de R y su alcance, matices y peligros
  • Cuándo y cómo utilizar escapes de caracteres, clases de caracteres, cuantificadores, anclas, alternancia y agrupación con R regex.
  • Varios ejemplos de aplicación de expresiones regulares y funciones de R
  • Algunas operaciones avanzadas con expresiones regulares en R

Estas habilidades y nociones le ayudarán a trabajar en R y en muchos otros lenguajes de programación ya que el concepto de expresiones regulares es el mismo para todos esos lenguajes y también la sintaxis de las regex es bastante similar para la mayoría de ellos.

Si está interesado en dominar sus habilidades con R, considere la posibilidad de explorar los siguientes cursos, pistas de habilidades y artículos de DataCamp:

Temas

Los mejores cursos de R

Course

Intermediate R

6 hr
597.5K
Continue your journey to becoming an R ninja by learning about conditional statements, loops, and vector functions.
See DetailsRight Arrow
Start Course
Ver másRight Arrow
Relacionado

blog

¿Qué es R? - Introducción al motor de cálculo estadístico

Aprenda todo lo que necesita saber sobre el lenguaje de programación R y descubra por qué es el lenguaje más utilizado en la ciencia de datos.
Summer Worsley's photo

Summer Worsley

18 min

R Project

blog

Las 8 mejores ideas de proyectos R para 2023

Descubra qué es R y todas las ventajas de utilizarlo, a la vez que ofrece ejemplos y nuevas ideas para un proyecto.
Elena Kosourova 's photo

Elena Kosourova

16 min

tutorial

K-Nearest Neighbors (KNN) Clasificación con R Tutorial

Aprenda a utilizar los paquetes 'class' y 'caret' de R, a ajustar los hiperparámetros y a evaluar el rendimiento del modelo.
Abid Ali Awan's photo

Abid Ali Awan

11 min

tutorial

Tutorial de RStudio

Descubra qué es RStudio y cómo instalarlo y empezar a utilizarlo
Elena Kosourova 's photo

Elena Kosourova

17 min

tutorial

Árboles de decisión en aprendizaje automático con R

Una guía completa para construir, visualizar e interpretar modelos de árboles de decisión con R.
Arunn Thevapalan's photo

Arunn Thevapalan

27 min

tutorial

Regresión logística en R Tutorial

Descubra todo sobre la regresión logística: en qué se diferencia de la regresión lineal, cómo ajustar y evaluar estos modelos en R con la función glm() y mucho más.
Vidhi Chugh's photo

Vidhi Chugh

14 min

See MoreSee More