Skip to content
SP StackPractices
beginner

Expresiones Regulares

Cómo usar expresiones regulares para matching de patrones, validación y extracción de texto en Python, JavaScript y Java.

Temas: data

Visión general

Las expresiones regulares (regex) son secuencias de caracteres que definen patrones de búsqueda. Son la herramienta estándar para validación de texto, extracción, sustitución y parsing en prácticamente todos los lenguajes de programación y editores de texto.

A pesar de su sintaxis críptica, regex es indispensable para trabajar con texto no estructurado, validación de formularios, parsing de logs y limpieza de datos.

Cuándo usarlo

Usa esta recipe cuando:

  • Validas direcciones de email, números de teléfono o IDs
  • Extraes datos de texto no estructurado o archivos de log
  • Reemplazas o formateas strings con reglas complejas
  • Divides texto en delimitadores dinámicos
  • Buscas patrones dentro de documentos grandes

Solución

Python

import re

text = "Contact us at support@example.com or sales@example.org"

# Buscar patrón de email
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
matches = re.findall(pattern, text)
print(matches)  # ['support@example.com', 'sales@example.org']

# Extraer grupos
match = re.search(r'(\w+)@(\w+\.\w+)', text)
if match:
    print(match.group(1))  # support
    print(match.group(2))  # example.com

# Reemplazar
new_text = re.sub(r'\b\w+@\w+\.\w+\b', '[REDACTED]', text)
print(new_text)  # Contact us at [REDACTED] or [REDACTED]

JavaScript

const text = "Contact us at support@example.com or sales@example.org";

// Match todos los emails
const pattern = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g;
const matches = text.match(pattern);
console.log(matches);  // ['support@example.com', 'sales@example.org']

// Extraer grupos
const groupPattern = /(\w+)@(\w+\.\w+)/;
const match = text.match(groupPattern);
if (match) {
  console.log(match[1]); // support
  console.log(match[2]); // example.com
}

// Reemplazar
const newText = text.replace(/\b\w+@\w+\.\w+\b/g, '[REDACTED]');
console.log(newText); // Contact us at [REDACTED] or [REDACTED]

Java

import java.util.regex.*;

String text = "Contact us at support@example.com or sales@example.org";

Pattern pattern = Pattern.compile("\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\\b");
Matcher matcher = pattern.matcher(text);

while (matcher.find()) {
    System.out.println(matcher.group());  // support@example.com, sales@example.org
}

// Extraer grupos
Pattern groupPattern = Pattern.compile("(\\w+)@(\\w+\\.\\w+)");
Matcher groupMatcher = groupPattern.matcher(text);
if (groupMatcher.find()) {
    System.out.println(groupMatcher.group(1));  // support
    System.out.println(groupMatcher.group(2));  // example.com
}

Explicación

  • Patrón: La cadena regex que define qué buscar
  • Matcher / Match object: Contiene el resultado de aplicar un patrón a texto
  • Grupos (()): Capturan sub-expresiones para extracción
  • Flags (i, g, m): Modifican el comportamiento (case-insensitive, global, multiline)
  • Clases de caracteres ([a-z], \d, \w): Coinciden con conjuntos de caracteres

Patrones comunes

PatrónDescripciónEjemplo
\d{3}-\d{2}-\d{4}Número de Seguro Social de EE.UU.123-45-6789
\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\bDirección IPv4192.168.1.1
https?://[^\s]+URLhttps://example.com
^\d{4}-\d{2}-\d{2}$Fecha ISO (YYYY-MM-DD)2024-03-15
^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$Email (básico)user@domain.com

Mejores prácticas

  • Siempre escapa caracteres especiales cuando construyas regex dinámicamente
  • Usa raw strings en Python (r'...') para evitar escapes dobles
  • Prefiere clases de caracteres explícitas sobre . (dot) para matching predecible
  • Ancla tus patrones con ^ y $ al validar strings completos
  • Testea con casos edge: strings vacíos, Unicode, inputs muy largos
  • Documenta patrones complejos con comentarios o el flag verbose (?x)

Errores comunes

  • Olvidar escapar backslashes (usa raw strings en Python)
  • Usar cuantificadores greedy (.*) cuando se necesita non-greedy (.*?)
  • No anclar patrones de validación, permitiendo matches parciales
  • Ignorar Unicode y caracteres internacionales en texto real
  • Escribir regex excesivamente complejas cuando una función de string simple basta

Preguntas frecuentes

P: ¿Debería usar regex para parsear HTML? R: No. HTML no es un lenguaje regular. Usa un parser de HTML apropiado (BeautifulSoup, DOM API, Jsoup).

P: ¿Cuál es la diferencia entre match() y search() en Python? R: match() verifica solo al principio del string. search() escanea todo el string.

P: ¿Cómo hago un regex case-insensitive? R: Usa el flag i (JavaScript), re.IGNORECASE (Python), o Pattern.CASE_INSENSITIVE (Java).