Las expresiones regulares (regex) son una de las herramientas mas poderosas de un desarrollador. Ya sea que estes validando entradas de usuario, analizando archivos de log o realizando operaciones complejas de buscar-y-reemplazar, regex ofrece una precision incomparable. Esta hoja de referencia regex completa cubre todos los conceptos principales.
Prueba cada patron en vivo en nuestro Regex Tester ->
Sintaxis basica: Anclas y clases de caracteres
Las anclas y clases de caracteres son la base de cada patron regex. Las anclas especifican donde debe ocurrir la coincidencia. Las clases definen que caracteres coincidir.
Anclas
Las anclas no coinciden con caracteres, sino con posiciones en la cadena.
| Pattern | Description | Example |
|---|---|---|
^ | Start of string (or line with m flag) | ^Hello matches "Hello World" |
$ | End of string (or line with m flag) | world$ matches "Hello world" |
\b | Word boundary | \bcat\b matches "cat" but not "catch" |
\B | Non-word boundary | \Bcat\B matches "concatenate" |
\A | Absolute start of string (Python, Ruby) | \AHello |
\Z | Absolute end of string (Python, Ruby) | bye\Z |
Clases de caracteres
Las clases de caracteres permiten coincidir un conjunto de caracteres en una posicion.
| Pattern | Description | Equivalent |
|---|---|---|
[abc] | Match a, b, or c | -- |
[^abc] | Match anything except a, b, c | -- |
[a-z] | Match any lowercase letter | -- |
[A-Z] | Match any uppercase letter | -- |
[0-9] | Match any digit | \d |
. | Match any character (except newline by default) | -- |
\d | Digit | [0-9] |
\D | Non-digit | [^0-9] |
\w | Word character | [a-zA-Z0-9_] |
\W | Non-word character | [^a-zA-Z0-9_] |
\s | Whitespace (space, tab, newline) | [ \t\n\r\f\v] |
\S | Non-whitespace | [^ \t\n\r\f\v] |
Caracteres especiales (metacaracteres)
Estos caracteres tienen significado especial. Para coincidir literalmente, escapalos con barra invertida.
Special characters that need escaping:
. ^ $ * + ? { } [ ] \ | ( )
To match a literal dot: \.
To match a literal star: \*
To match a literal pipe: \|
To match a backslash: \\Cuantificadores: cuantas veces coincidir
Los cuantificadores controlan las repeticiones. Por defecto son codiciosos. Agregar ? los hace perezosos.
| Greedy | Lazy | Description |
|---|---|---|
* | *? | 0 or more times |
+ | +? | 1 or more times |
? | ?? | 0 or 1 time (optional) |
{n} | {n}? | Exactly n times |
{n,} | {n,}? | n or more times |
{n,m} | {n,m}? | Between n and m times |
Codicioso vs. Perezoso
El patron codicioso <.*> coincide con toda la cadena, mientras que <.*?> coincide solo con la primera etiqueta.
// Input string:
const str = '<b>bold</b> and <i>italic</i>';
// Greedy: matches from first < to LAST >
str.match(/<.*>/);
// Result: '<b>bold</b> and <i>italic</i>'
// Lazy: matches from first < to FIRST >
str.match(/<.*?>/);
// Result: '<b>'Grupos y captura
Los grupos permiten tratar multiples caracteres como una unidad y extraer porciones coincidentes.
Grupos de captura
Envuelve una subexpresion con (...) para capturar su coincidencia.
// Capturing group example
const dateRegex = /^(\d{4})-(\d{2})-(\d{2})$/;
const match = '2026-02-10'.match(dateRegex);
// match[0] = '2026-02-10' (full match)
// match[1] = '2026' (year)
// match[2] = '02' (month)
// match[3] = '10' (day)
// Backreference: match repeated words
const repeated = /\b(\w+)\s+\1\b/;
repeated.test('the the'); // true
repeated.test('the cat'); // falseGrupos con nombre
Los grupos con nombre mejoran la legibilidad con (?<nombre>...).
// Named groups in JavaScript
const dateRegex = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/;
const match = '2026-02-10'.match(dateRegex);
// match.groups.year = '2026'
// match.groups.month = '02'
// match.groups.day = '10'# Named groups in Python
import re
pattern = r'^(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})$'
m = re.match(pattern, '2026-02-10')
# m.group('year') = '2026'
# m.group('month') = '02'
# m.group('day') = '10'Grupos sin captura
Usa (?:...) cuando necesites agrupar sin capturar.
// Non-capturing group
const regex = /(?:https?|ftp):\/\/[^\s]+/;
// Groups the protocol options without capturing them
// Only the full URL is in match[0]Alternancia (O)
Usa el pipe | para coincidir con una de varias alternativas.
// Alternation examples
/cat|dog/ // Match "cat" or "dog"
/(red|blue) car/ // Match "red car" or "blue car"
/^(GET|POST|PUT|DELETE)\s/ // Match HTTP methodsLookahead y Lookbehind
Los lookarounds verifican si un patron existe antes o despues de la posicion actual, sin consumir caracteres.
| Syntax | Type | Description |
|---|---|---|
(?=...) | Positive lookahead | What follows must match |
(?!...) | Negative lookahead | What follows must NOT match |
(?<=...) | Positive lookbehind | What precedes must match |
(?<!...) | Negative lookbehind | What precedes must NOT match |
Lookahead positivo (?=...)
Coincide con una posicion seguida por el patron especificado.
// Match a number followed by "px"
/\d+(?=px)/
// "20px 30em 40px" → matches "20" and "40" (not "30")
// Password: must contain at least one digit
/^(?=.*\d).{8,}$/Lookahead negativo (?!...)
Coincide con una posicion no seguida por el patron especificado.
// Match "cat" NOT followed by "fish"
/cat(?!fish)/
// "catfish catdog" → matches "cat" in "catdog" only
// Match numbers NOT followed by a unit
/\d+(?!\s*(px|em|rem|%))/Lookbehind positivo (?<=...)
Coincide con una posicion precedida por el patron especificado.
// Match a number preceded by "$"
/(?<=\$)\d+(\.\d{2})?/
// "$49.99 and €29.99" → matches "49.99" only
// Extract value after "price:"
/(?<=price:\s*)\d+/Lookbehind negativo (?<!...)
Coincide con una posicion no precedida por el patron especificado.
// Match "cat" NOT preceded by "wild"
/(?<!wild)cat/
// "wildcat housecat" → matches "cat" in "housecat" only
// Match digits not preceded by a minus sign
/(?<!-)\b\d+\b/Nota: Los lookbehinds no estan soportados en todos los motores regex.
Flags de Regex (modificadores)
Los flags modifican como el motor regex interpreta el patron.
| Flag | Name | Description | Example |
|---|---|---|---|
g | Global | Find all matches, not just the first | /cat/g finds all "cat" occurrences |
i | Case-insensitive | Match upper and lowercase interchangeably | /hello/i matches "Hello", "HELLO" |
m | Multiline | ^ and $ match line starts/ends | /^start/m matches at each line start |
s | Dotall (Single-line) | . matches newline characters too | /a.b/s matches "a\nb" |
u | Unicode | Enable full Unicode matching | /\u{1F600}/u matches emoji |
y | Sticky | Match only at lastIndex position | Used for tokenizing / lexing |
// Combining flags
const regex = /^hello world$/gim;
// In Python, flags are constants:
import re
pattern = re.compile(r'^hello world$', re.IGNORECASE | re.MULTILINE)
// In Go, use inline flags:
// (?i) for case-insensitive, (?m) for multiline, (?s) for dotall
regexp.MustCompile("(?im)^hello world$")Patrones comunes - Referencia rapida
Los patrones regex mas utilizados en un vistazo.
| Use Case | Pattern |
|---|---|
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ | |
| URL (HTTP/S) | ^https?:\/\/[^\s]+$ |
| IPv4 Address | ^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$ |
| Date (YYYY-MM-DD) | ^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$ |
| Time (HH:MM:SS) | ^([01]\d|2[0-3]):[0-5]\d:[0-5]\d$ |
| Hex Color | ^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$ |
| Strong Password | ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&]).{8,}$ |
| Phone (E.164) | ^\+[1-9]\d{1,14}$ |
| UUID | ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$ |
| Semantic Version | ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-[\w.]+)?(\+[\w.]+)?$ |
| HTML Tag | <([a-zA-Z][a-zA-Z0-9]*)\b[^>]*>(.*?)<\/\1> |
| Trim Whitespace | ^\s+|\s+$ |
Prueba todos estos patrones con nuestro Regex Tester ->
Regex en diferentes lenguajes de programacion
La sintaxis es mayormente universal, pero cada lenguaje tiene su propia API.
JavaScript
// Creating regex in JavaScript
const regex1 = /^\d+$/; // Literal syntax
const regex2 = new RegExp('^\\d+$'); // Constructor (needs double-escape)
// Testing
regex1.test('12345'); // true
// Matching
'hello world'.match(/\w+/g); // ['hello', 'world']
// Replacing
'2026-02-10'.replace(
/^(\d{4})-(\d{2})-(\d{2})$/,
'$2/$3/$1'
); // '02/10/2026'
// matchAll (ES2020) - get all matches with groups
const text = 'Price: $10, Tax: $2';
for (const m of text.matchAll(/\$(\d+)/g)) {
console.log(m[0], m[1]);
// '$10' '10', then '$2' '2'
}
// Named groups (ES2018+)
const { groups } = '2026-02-10'.match(
/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
);
console.log(groups.year); // '2026'Python
import re
# Compile for reuse (recommended)
pattern = re.compile(r'^\d+$')
# Test if the entire string matches
pattern.match('12345') # Match object (truthy)
pattern.match('abc') # None (falsy)
# Search anywhere in the string
re.search(r'\d+', 'abc 123 def') # Finds '123'
# Find all matches
re.findall(r'\w+', 'hello world') # ['hello', 'world']
# Replace
re.sub(
r'^(\d{4})-(\d{2})-(\d{2})$',
r'\2/\3/\1',
'2026-02-10'
) # '02/10/2026'
# Named groups
m = re.match(
r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})',
'2026-02-10'
)
m.group('year') # '2026'
m.group('month') # '02'
# Flags
re.findall(r'^start', text, re.MULTILINE | re.IGNORECASE)
# Split by pattern
re.split(r'[,;\s]+', 'a, b; c d') # ['a', 'b', 'c', 'd']Go (Golang)
package main
import (
"fmt"
"regexp"
)
func main() {
// Compile (panics on invalid pattern)
re := regexp.MustCompile(`^\d+$`)
// Test
fmt.Println(re.MatchString("12345")) // true
fmt.Println(re.MatchString("abc")) // false
// Find first match
re2 := regexp.MustCompile(`\d+`)
fmt.Println(re2.FindString("abc 123 def")) // "123"
// Find all matches
fmt.Println(re2.FindAllString("10 cats and 20 dogs", -1))
// ["10", "20"]
// Replace
re3 := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)
result := re3.ReplaceAllString("2026-02-10", "$2/$3/$1")
fmt.Println(result) // "02/10/2026"
// Named groups
re4 := regexp.MustCompile(`(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})`)
match := re4.FindStringSubmatch("2026-02-10")
for i, name := range re4.SubexpNames() {
if name != "" {
fmt.Printf("%s: %s\n", name, match[i])
}
}
// year: 2026, month: 02, day: 10
// Inline flags: (?i) case-insensitive, (?m) multiline, (?s) dotall
re5 := regexp.MustCompile(`(?i)hello`)
fmt.Println(re5.MatchString("HELLO")) // true
}Go usa RE2, que no soporta lookaheads, lookbehinds ni backreferences.
Consejos de rendimiento y buenas practicas
Se especifico: Usa [a-zA-Z] en lugar de . cuando sea posible.
Evita el backtracking catastrofico: Cuantificadores anidados como (a+)+ pueden causar complejidad exponencial.
// BAD: Catastrophic backtracking risk
const bad = /^(a+)+$/;
bad.test('aaaaaaaaaaaaaaaaaaaaa!'); // Extremely slow!
// GOOD: Flatten nested quantifiers
const good = /^a+$/;
good.test('aaaaaaaaaaaaaaaaaaaaa!'); // Instant: falseUsa grupos sin captura: (?:...) es mas eficiente cuando no necesitas capturar.
Compila una vez: En Python y Go, compila tu regex una vez y reutiliza el objeto.
# Python: compile once, reuse many times
import re
email_re = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')
# Fast: uses pre-compiled pattern
for addr in addresses:
if email_re.match(addr):
print(f"Valid: {addr}")Prueba incrementalmente: Construye patrones complejos paso a paso.
Prueba cada patron en vivo en nuestro Regex Tester ->
Preguntas frecuentes
Que es una hoja de referencia regex y por que la necesito?
Es una guia de referencia rapida con sintaxis, metacaracteres, cuantificadores, flags y patrones comunes. Incluso los desarrolladores experimentados no pueden memorizar todo.
Cual es la diferencia entre .* y .*? en regex?
.* es codicioso (coincidencia mas larga), .*? es perezoso (coincidencia mas corta). Usa perezoso para detenerte en el primer delimitador.
Todos los lenguajes soportan la misma sintaxis regex?
La mayoria soporta PCRE. Las funciones avanzadas varian: JavaScript agrego lookbehinds en ES2018, Go (RE2) no los soporta.
Como puedo probar y depurar patrones regex?
Usa un probador regex interactivo como nuestra herramienta Regex Tester que muestra coincidencias en tiempo real.
Que es el backtracking catastrofico?
Ocurre cuando el motor toma un tiempo exponencial. Evita cuantificadores anidados y se especifico con las clases de caracteres.