Expresiones regulares (regex)

Qué es una expresión regular?

Son patrones utilizados para encontrar coincidencias dentro de 📑

¿Para qué se utilizan?

  • Búsqueda avanzada en texto libre

  • Validación de formularios

  • Extracción de datos de grandes volúmenes de texto.

  • Sustitución de patrones en textos masivos.

¿Qué es una expresión regular?

Ejemplo  <- "((?<=(\\bh?t[-/\\.\\\\ ]?a|\\bp[-/\\.\\\\ ]?a|presi.n|
arterial|tensi.n|tens.|\\bb\\.?d|\\bb\\.?i)
?[\\.:\\,=]? ?)((2[0-5][0-9]|1[0-9][0-9]|0[5-9][0-9]|
[5-9][0-9])(( ?)[/\\-\\\\ ]
( ?))(0[3-9][0-9]|1[0-3][0-9]|[3-9][0-9])))|((?<=\\D|\\b)
((2[0-5][0-9]|1[0-9][0-9]|0[5-9][0-9]
|[5-9][0-9])(( ?)[/\\-\\\\ ]( ?))(0[3-9][0-9]|1[0-2][0-9]|
[3-9][0-9]))(?= ? ?(mm|b\\.?d\\.?\\b|b\\.?i\\.?\\b)))"

Características

  • Son trasversales a todos los lenguajes de programación

  • Asustan y parecen inentendibles

regex en R

Para que r entienda que es una expresión regular usamos la función regex()

library(stringr)
library(tidyverse)
#style_mono_quarto(path_scss = "custom.scss")
texto <- "Hola mundo, hola universo"
patron <- regex("mundo",T)

# Detecta si el patrón está presente en el texto
str_detect(texto, patron)
[1] TRUE

Librería a utilizar


El paquete stringr proporciona un conjunto de funciones diseñadas para que trabajar con cadenas de texto

Funciones stringr : coincidencia

  • str_detect(texto, patron): Detecta si un patrón está presente en una cadena (devuelve TRUE/FALSE).

  • str_which(texto, patron): Devuelve los índices de las cadenas que coinciden con un patrón.

  • str_count(texto, patron): Cuenta cuántas veces aparece un patrón en cada cadena.

Funciones stringr : coincidencia

  • str_subset(texto, patron): Filtra las cadenas que contienen un patrón.

  • str_match(texto, patron): Extrae las coincidencias del patrón con grupos de captura.

  • str_extract(texto, patronn): Extrae la primera coincidencia del patrón.

  • str_extract_all(texto, patron): Extrae todas las coincidencias del patrón

Funciones stringr : reemplazo y división

  • str_replace(texto, patron, reemplazo): Reemplaza la primera coincidencia del patrón por otro texto.

  • tr_replace_all(texto, patron, reemplazo): Reemplaza todas las coincidencias del patrón.

  • str_split(string, pattern): Divide la cadena en partes basadas en un patrón.

¿Cómo armar expresiones regulares?

Mi primera regex

Vamos a imaginar que tenemos un excel con las anotaciones de las sesiones de terapia de un médico, y en base a ese campo de “notas” tenemos que traernos aquellos registros que tienen determinadas características

Armando expresiones regulares

La columna id tiene el identificador de historia clinica del paciente y notas las anotaciones del profesional

notas_sesiones <- tibble::tibble(id = 1:13,
                        nota = c("ausente", "ausente al turno", "tuvo un papa ausente", "no concurrió al turno", "su mamá estaba ausente", "no vino al turno su mama", "no vino turno", "mi hermana estaba ausente een casa","La ausencia de luz fue larga.", "se hizo un pap", "hermano concurre al turno", "DNI: 12345678", "ultima consulta en 2005"))

head(notas_sesiones)
# A tibble: 6 × 2
     id nota                    
  <int> <chr>                   
1     1 ausente                 
2     2 ausente al turno        
3     3 tuvo un papa ausente    
4     4 no concurrió al turno   
5     5 su mamá estaba ausente  
6     6 no vino al turno su mama

Observamos la base

DT::datatable(notas_sesiones)

Expresión regular: ausentes

Me gustaría traerme todos los id de los pacientes que estuvieron ausentes a su sesión

➡️ con poner solo ausente no alcanza

patron <- regex("ausente",T)

notas_sesiones |>
  filter(str_detect(nota, patron))
# A tibble: 5 × 2
     id nota                              
  <int> <chr>                             
1     1 ausente                           
2     2 ausente al turno                  
3     3 tuvo un papa ausente              
4     5 su mamá estaba ausente            
5     8 mi hermana estaba ausente een casa

Inicio de la expresión

^ indica que la expresión a buscar debe estar al inicio del vector o fila | es un “o”

patron <- regex("^ausente",T)

notas_sesiones |>
  filter(str_detect(nota, patron))
# A tibble: 2 × 2
     id nota            
  <int> <chr>           
1     1 ausente         
2     2 ausente al turno

Caracteres lógicos

| es un “o” lógico en regex
() Agrupa expresiones para combinarlas con | u otros operadores

patron <- regex("^ausente|no (concurre|asiste|vino) al turno",T)

notas_sesiones |>
  filter(str_detect(nota, patron))
# A tibble: 4 × 2
     id nota                     
  <int> <chr>                    
1     1 ausente                  
2     2 ausente al turno         
3     6 no vino al turno su mama 
4    11 hermano concurre al turno

????

? hace que lo que le siga sea opcional

patron <- regex("^ausente|no (concurre|asiste|vino) ?al turno",T)

notas_sesiones |>
  filter(str_detect(nota, patron))
# A tibble: 4 × 2
     id nota                     
  <int> <chr>                    
1     1 ausente                  
2     2 ausente al turno         
3     6 no vino al turno su mama 
4    11 hermano concurre al turno

Borde de palabra

\\b limite de palabra boundary

patron <- regex("^ausente|\\bno (concurre|asiste|vino) ?al turno",T)

notas_sesiones |>
  filter(str_detect(nota, patron))
# A tibble: 3 × 2
     id nota                    
  <int> <chr>                   
1     1 ausente                 
2     2 ausente al turno        
3     6 no vino al turno su mama

el punto

. indica que podria ser cualquier caracter

Ejemplo: Si quiero traerme todas las notas que digan mamá

patron <- regex("mamá|papá",T)

notas_sesiones |>
  filter(str_detect(nota, patron))
# A tibble: 1 × 2
     id nota                  
  <int> <chr>                 
1     5 su mamá estaba ausente

el punto

. indica que podria ser cualquier caracter

Ejemplo: Si quiero traerme todas las notas que digan mamá

patron <- regex("\\bmam.\\b|\\bpap.\\b",T)

notas_sesiones |>
  filter(str_detect(nota, patron))
# A tibble: 3 × 2
     id nota                    
  <int> <chr>                   
1     3 tuvo un papa ausente    
2     5 su mamá estaba ausente  
3     6 no vino al turno su mama

Cantidad de repeticiones o catacteres

{n} exactamente n repeticiones.

{n,} al menos n repeticiones.

{n,m} entre n y m repeticiones.

patron <- regex("e{2,3}", TRUE) 
notas_sesiones |>
  filter(str_detect(nota, patron))
# A tibble: 1 × 2
     id nota                              
  <int> <chr>                             
1     8 mi hermana estaba ausente een casa

Cantidad de repeticiones o catacteres

Si se le pone un . antes, busca cercanía entre tantos caracteres

Ejemplo: Busco mamá o papá que se encuentren cerca de “ausente”

patron <- regex("(\\bmam.\\b|\\bpap.\\b).{0,15}ausent", TRUE) 
notas_sesiones |>
  filter(str_detect(nota, patron))
# A tibble: 2 × 2
     id nota                  
  <int> <chr>                 
1     3 tuvo un papa ausente  
2     5 su mamá estaba ausente

Clases de caracteres

[aeiou] busca cualquier vocal.

[0-9] busca cualquier número.

[^aeiou] busca cualquier letra que no sea vocal.

patron <- regex("[0-9]", TRUE) 
notas_sesiones |>
  filter(str_detect(nota, patron))
# A tibble: 2 × 2
     id nota                   
  <int> <chr>                  
1    12 DNI: 12345678          
2    13 ultima consulta en 2005

Clases de caracteres

\\d busca números.

\\D busca letras o símbolos.

patron <- regex("\\d{8}", TRUE) #busco solo 8 digitos
notas_sesiones |>
  filter(str_detect(nota, patron))
# A tibble: 1 × 2
     id nota         
  <int> <chr>        
1    12 DNI: 12345678

Espacios

\\s+ encuentra uno o más espacios.

\\S+ encuentra palabras sin espacios.

patron <- regex("\\s", TRUE)  # Encuentra espacios

frases <- tibble(nota = c("sinespacio", "con  espacios"))

frases |>
  filter(str_detect(nota, patron))
# A tibble: 1 × 1
  nota         
  <chr>        
1 con  espacios

Recursos

  • cheatsheet con las funciones de stringr

  • más caracteres para armado de expresiones regulares

  • URL para probar expresiones regulares: https://regex101.com/

Recreo

Volvemos en 10 minutos para comenzar con el taller