Hoja de Referencia de Expresiones Regulares para Desarrolladores

· 12 min de lectura

Tabla de Contenidos

Introducción a las Expresiones Regulares

Las expresiones regulares (regex) son herramientas poderosas de coincidencia de patrones que todo desarrollador debería dominar. Proporcionan una forma concisa y declarativa de buscar, validar y manipular datos de texto sin escribir código verboso de manipulación de cadenas.

Ya sea que estés construyendo validación de formularios, analizando archivos de registro, extrayendo datos de APIs o limpiando conjuntos de datos, regex ofrece una solución elegante. Un solo patrón regex puede reemplazar docenas de líneas de lógica condicional, haciendo tu código más mantenible y menos propenso a errores.

Los lenguajes de programación modernos como JavaScript, Python, Java, PHP y Ruby tienen soporte integrado para regex. Una vez que aprendes la sintaxis, puedes aplicar estas habilidades en prácticamente cualquier entorno de desarrollo.

Consejo profesional: Las expresiones regulares pueden parecer crípticas al principio, pero siguen patrones consistentes. Comienza con expresiones simples y construye gradualmente la complejidad a medida que ganas confianza. Usa probadores de regex en línea para experimentar y visualizar coincidencias en tiempo real.

Sintaxis Básica y Elementos

Comprender los bloques de construcción fundamentales de regex es esencial antes de abordar patrones complejos. Estos elementos centrales forman la base de cada expresión regular que escribirás.

Caracteres Literales

Los patrones regex más simples coinciden con caracteres literales exactamente como aparecen. El patrón cat coincide con la cadena "cat" dondequiera que aparezca en tu texto.

La mayoría de los caracteres alfanuméricos son literales, pero ciertos caracteres especiales (llamados metacaracteres) tienen significados especiales y deben escaparse con una barra invertida cuando quieres que coincidan literalmente.

Metacaracteres Esenciales

Patrón Descripción Ejemplo Coincide
. Coincide con cualquier carácter individual excepto nueva línea c.t "cat", "cot", "c9t"
^ Afirma posición al inicio de la cadena ^Hello "Hello world" (solo al inicio)
$ Afirma posición al final de la cadena world$ "Hello world" (solo al final)
* Coincide con 0 o más repeticiones ab*c "ac", "abc", "abbc"
+ Coincide con 1 o más repeticiones ab+c "abc", "abbc" (no "ac")
? Coincide con 0 o 1 ocurrencia colou?r "color", "colour"
| Alternancia (operador OR) cat|dog "cat" o "dog"
\ Escapa caracteres especiales \. Carácter de punto literal

Escapando Caracteres Especiales

Cuando necesitas coincidir metacaracteres literalmente, añádeles un prefijo con una barra invertida. Por ejemplo, para coincidir con un punto literal, usa \. en lugar de solo .

Los caracteres comunes que necesitan escaparse incluyen: . * + ? ^ $ { } [ ] ( ) | \

// Coincidir con un signo de interrogación literal
const pattern = /What\?/;
pattern.test("What?"); // true

// Coincidir con una cantidad en dólares
const price = /\$\d+\.\d{2}/;
price.test("$19.99"); // true

Clases de Caracteres y Cuantificadores

Las clases de caracteres te permiten coincidir con cualquier carácter de un conjunto específico, mientras que los cuantificadores controlan cuántas veces debe repetirse un patrón. Juntos, forman la columna vertebral de la coincidencia de patrones flexible.

Clases de Caracteres Predefinidas

Clase Descripción Equivalente Ejemplo
\d Cualquier dígito [0-9] \d{3} coincide con "123"
\D Cualquier no-dígito [^0-9] \D+ coincide con "abc"
\w Carácter de palabra (alfanumérico + guión bajo) [A-Za-z0-9_] \w+ coincide con "user_123"
\W Carácter no-palabra [^A-Za-z0-9_] \W coincide con "@" o " "
\s Espacio en blanco (espacio, tabulación, nueva línea) [ \t\n\r\f\v] \s+ coincide con " "
\S No-espacio en blanco [^ \t\n\r\f\v] \S+ coincide con "hello"

Conjuntos de Caracteres Personalizados

Los corchetes definen conjuntos de caracteres personalizados. El patrón [aeiou] coincide con cualquier vocal individual, mientras que [0-9a-fA-F] coincide con cualquier dígito hexadecimal.

Usa un acento circunflejo dentro de los corchetes para negar el conjunto: [^0-9] coincide con cualquier carácter que NO sea un dígito.

// Coincidir con cualquier vocal
const vowels = /[aeiou]/gi;
"Hello World".match(vowels); // ["e", "o", "o"]

// Coincidir solo con consonantes
const consonants = /[^aeiou\s]/gi;
"Hello".match(consonants); // ["H", "l", "l"]

Cuantificadores en Detalle

Los cuantificadores especifican cuántas veces debe coincidir el elemento precedente. Son codiciosos por defecto, lo que significa que coinciden con tanto texto como sea posible.

Consejo rápido: Añade un signo de interrogación después de cualquier cuantificador para hacerlo no-codicioso (perezoso). Por ejemplo, .*? coincide con la menor cantidad de caracteres posible en lugar de la mayor cantidad posible. Esto es crucial al extraer contenido entre delimitadores.

Anclas y Límites de Palabras

Las anclas no coinciden con caracteres—coinciden con posiciones en la cadena. Son esenciales para la coincidencia precisa de patrones cuando necesitas asegurar que el texto aparezca en ubicaciones específicas.

Anclas de Posición

El acento circunflejo ^ coincide con el inicio de una cadena (o línea en modo multilínea), mientras que el signo de dólar $ coincide con el final. Estos son invaluables para la validación donde toda la cadena debe coincidir con un patrón.

// Validar que toda la cadena sean dígitos
const onlyDigits = /^\d+$/;
onlyDigits.test("12345"); // true
onlyDigits.test("123abc"); // false

// Coincidir con líneas que comienzan con "Error"
const errorLines = /^Error/gm;
const logs = "Info: Starting\nError: Failed\nError: Timeout";
logs.match(errorLines); // ["Error", "Error"]

Límites de Palabras

El ancla \b coincide con límites de palabras—posiciones entre caracteres de palabra y no-palabra. Es perfecta para coincidir con palabras completas sin coincidir accidentalmente con partes de palabras más grandes.

El ancla \B coincide con posiciones que NO son límites de palabras.

// Coincidir con "cat" solo como palabra completa
const wholeCat = /\bcat\b/;
wholeCat.test("cat"); // true
wholeCat.test("cats"); // false
wholeCat.test("concatenate"); // false

// Coincidir con "cat" dentro de palabras
const partialCat = /\Bcat\B/;
partialCat.test("concatenate"); // true
partialCat.test("cat"); // false

Los límites de palabras son particularmente útiles para operaciones de búsqueda y reemplazo donde quieres evitar coincidencias parciales. También son esenciales al construir resaltadores de sintaxis o analizadores de código.

Grupos y Captura

Los paréntesis en regex sirven para múltiples propósitos: agrupan partes de patrones juntas, capturan texto coincidente para uso posterior y habilitan referencias hacia atrás dentro del patrón mismo.

Grupos de Captura

Los paréntesis crean grupos de captura numerados que almacenan el texto coincidente. Puedes referenciar estas capturas en cadenas de reemplazo o extraerlas programáticamente.

// Extraer componentes de fecha
const datePattern = /(\d{4})-(\d{2})-(\d{2})/;
const match = "2026-03-31".match(datePattern);
// match[0]: "2026-03-31" (coincidencia completa)
// match[1]: "2026" (año)
// match[2]: "03" (mes)
// match[3]: "31" (día)

// Reformatear fechas usando capturas
const text = "Date: 2026-03-31";
const reformatted = text.replace(/(\d{4})-(\d{2})-(\d{2})/, "$2/$3/$1");
// Resultado: "Date: 03/31/2026"

Grupos sin Captura

Usa (?:...) para agrupar patrones sin crear una captura. Esto mejora el rendimiento y mantiene tu numeración de capturas limpia cuando solo necesitas agrupación para alternancia o cuantificadores.

// Agrupar sin capturar
const protocol = /(?:https?|ftp):\/\//;
protocol.test("https://example.com"); // true

// Comparar con captura (sobrecarga innecesaria)
const protocolCapture = /(https?|ftp):\/\//;
// Crea un grupo de captura extra que no necesitamos

Grupos de Captura Nombrados

Los motores regex modernos soportan capturas nombradas usando la sintaxis (?<name>...). Esto hace que tus patrones sean autodocumentados y más fáciles de mantener.

// Capturas nombradas para claridad
const emailPattern = /(?<user>[\w.]+)@(?<domain>[\w.]+)/;
const match = "[email protected]".match(emailPattern);
console.log(match.groups.user); // "john.doe"
console.log(match.groups.domain); // "example.com"

// Usar en reemplazos
const masked = "[email protected]".replace(
  /(?<user>[\w.]+)@(?<domain>[\w.]+)/,
  "***@$<domain>"
);
// Resultado: "***@example.com"

Referencias Hacia Atrás

Referencia capturas anteriores dentro del mismo patrón usando \1, \2, etc. Esto es poderoso para coincidir con patrones repetidos o reflejados.

// Coincidir con palabras repetidas
const repeated = /\b(\w+)\s+\1\b/;
repeated.test("hello hello"); // true
repeated.test("hello world"); // false

// Coincidir con etiquetas HTML
const htmlTag = /<(\w+)>.*?<\/\1>/;
htmlTag.test("<div>content</div>"); // true
htmlTag.test("<div>content</span>"); // false

Banderas y Modificadores de Regex

Las banderas modifican cómo el motor regex interpreta tu patrón. Se añaden después del delimitador de cierre en la mayoría de los lenguajes (ej., /pattern/flags en JavaScript).

Banderas Comunes

// Búsqueda insensible a mayúsculas
const pattern = /hello/i;
pattern.test("HELLO"); // true
pattern.test("Hello"); // true

// Bandera global para múltiples coincidencias
const digits = /\d+/g;
"Phone: 555-1234, Fax: 555-5678".match(digits);
// ["555", "1234", "555", "5678"]

// Modo multilínea
const headers = /^#.+$/gm;
const markdown = "# Title\nContent\n## Subtitle";
markdown.match(headers); // ["# Title", "## Subtitle"]

Consejo profesional: La bandera global cambia cómo se comportan métodos como exec() y test()—mantienen estado entre llamadas. Si estás obteniendo resultados inesperados, verifica si necesitas la bandera global o si está causando problemas con la coincidencia con estado.

Patrones Comunes y sus Aplicaciones

Exploremos patrones regex probados en batalla para tareas comunes de desarrollo. Estos patrones han sido refinados a través del uso en el mundo real y manejan casos extremos que podrías no considerar inicialmente.

Validación de Correo Electrónico

La validación de correo electrónico es notoriamente compleja debido a las especificaciones RFC, pero este patrón práctico maneja el 99% de las direcciones de correo electrónico del mundo real:

const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;

// Correos válidos
emailPattern.test("[email protected]"); // true
emailPattern.test("[email protected]"); // true

// Correos inválidos
emailPattern.test("invalid@"); // false
emailPattern.test("@example.com"); // false
emailPattern.test("[email protected]"); // false

Para aplicaciones de producción, considera usar una biblioteca dedicada de validación de correo electrónico que maneje dominios internacionalizados y todos los casos extremos de RFC. También puedes usar nuestra Herramienta de Validación de Correo Electrónico para probar patrones de correo electrónico de forma interactiva.

Coincidencia de URL

Coincide y extrae URLs del texto con este patrón integral:

const urlPattern
We use cookies for analytics. By continuing, you agree to our Privacy Policy.