Quiz: Dominio de Expresiones Regulares
¿Dominas alguna expresión regular salvaje?
¿Listo para enfrentarte a algunas expresiones regulares? 🤼♂️
Pon a prueba tu conocimiento de RegEx con preguntas que cubren patrones básicos, cuantificadores, grupos y esas complicadas aserciones de look‑around. Desde la coincidencia de cadenas simples hasta la validación de patrones complejos, ¿puedes identificar la expresión regular correcta?
¿Qué coincide?
'cat CAT Cat'.match(/cat/g)Este patrón usa g, pero no i:
gencuentra todas las coincidencias- Sin
i, la coincidencia distingue mayúsculas y minúsculas
Sin la bandera i, solo coincide “cat” en minúsculas.
Esto es particularmente útil al manejar entrada de usuario o HTML donde el caso puede variar.
¿Qué devolverá este código?
const words = ['cat', 'hat', 'what', 'bat'];words.filter(word => word.match(/^[ch]at/))El patrón /^[ch]at/ coincide con cadenas que:
- Comienzan (
^) con ‘c’ o ‘h’ (eso es lo que[ch]significa: una clase de caracteres que coincide con un carácter) - Seguidos literalmente de ‘at’
Por lo tanto, solo “cat” y “hat” coinciden con este patrón. El método filter() conserva solo los elementos que coinciden.
¿Qué coincidirá esto?
'<div>Hello</div><div>World</div>'.match(/<div>.*?<\/div>/g)El patrón /<div>.*?<\/div>/g usa coincidencia no codiciosa con *?, lo que significa:
- Coincidir
<div> - Coincidir cualquier carácter (
.*) pero el menor número posible (?) - Hasta encontrar
</div> - La bandera
ghace que coincida todas las ocurrencias
Sin el ?, el .* codicioso coincidiría todo desde el primer <div> hasta el último </div>, produciendo una única coincidencia grande. Con ?, coincide cada par por separado.
¿Qué devolverá esto?
'hello\nworld'.match(/\w+/g)El patrón \w+ coincide con uno o más caracteres de palabra. Aunque la cadena contiene un salto de línea, \w coincide con:
- Letras (a-z, A-Z)
- Números (0-9)
- Guion bajo (_)
Así, el salto de línea actúa como un límite de palabra y obtenemos dos coincidencias. Si hubiéramos usado .*, no coincidiría con el salto de línea por defecto (necesitarías la bandera s para eso).
¿Qué coincidirá esto?
'$100 and €50'.match(/\d+(?=[\$€])/g)Este patrón no coincidirá con nada porque el look-ahead está al revés. Si quieres dígitos precedidos por $ o €, usa un look-behind: /(?<=[\$€])\d+/g.
Los look-aheads verifican lo que viene después de la posición actual. El patrón tal como está busca:
- Uno o más dígitos (
\d+) - Seguidos por (
(?=...)) ya sea$o€([\$€])
Como no hay números seguidos de símbolos de moneda (están precedidos por ellos), no obtenemos coincidencias.
¿Qué coincidirá?
'cat cats category'.match(/\bcat\b/g)El \b representa un límite de palabra, que coincide:
- Entre un carácter de palabra y un carácter no palabra
- Al inicio o al final de la cadena si hay un carácter de palabra
Así, /\bcat\b/ coincide con “cat” solo cuando es una palabra completa, no parte de otra palabra.
- ✅ “cat” (rodeado de espacios)
- ❌ “cats” (no hay límite después de “cat”)
- ❌ “category” (no hay límite después de “cat”)
¿Cuál es la salida?
'banana'.match(/a/g)El modificador g (global) cambia cómo se comporta match():
- Sin
g: devuelve la primera coincidencia con los grupos de captura - Con
g: devuelve un array con todas las cadenas coincidentes
En este caso, encuentra todas las ocurrencias de “a” en “banana”.
Nota: Si necesitas tanto todas las coincidencias COMO los grupos de captura, usa matchAll() o el método exec() en un bucle.
¿Qué coincide con este patrón?
'abc123 def456'.match(/(?<!abc)\d+/g)El look-behind negativo (?<!abc) asegura que los dígitos no estén precedidos por “abc”:
- ❌ “123” (precedido por “abc”)
- ✅ “23” (precedido por “abc1”)
- ✅ “456” (precedido por “def”)
JavaScript admite aserciones de look-behind en motores modernos. Este ejemplo usa un look-behind de longitud fija: abc siempre tiene tres caracteres. El look-behind de longitud variable es el caso más complicado y depende del motor.
Nota: El soporte de look-behind es relativamente reciente en JavaScript. Consulta la compatibilidad de navegadores si necesitas soportar navegadores antiguos.
¿Qué devolverá esto?
'2029-12-31'.match(/(\d{4})-(\d{2})-(\d{2})/).slice(1)El patrón usa tres grupos de captura:
(\d{4})captura el año(\d{2})captura el mes(\d{2})captura el día
match() sin la bandera g devuelve:
- Índice 0: Coincidencia completa
- Índice 1+: Grupos de captura
slice(1) es un truco común para obtener solo los grupos de captura.
¿Cuál será el resultado de esto?
"123aBc".match(/^\d+(?![a-z])/ig)El lookahead negativo (?![a-z]) asegura que no haya letras minúsculas después de los dígitos. Como la parte “3aBc” contiene una letra minúscula después de los dígitos, esa porción no coincide. Por lo tanto, solo coincide el comienzo “12”.
¿Qué se devuelve?
'a,b,c'.split(/(?<=,)/)El patrón /(?<=,)/ es un look-behind que coincide después de una coma:
a,(después de la coma)b,(después de la coma)c(sin coma después)
El look-behind no consume la coma, por lo que la coma queda adherida al segmento anterior en el resultado del split.
Esto es útil cuando quieres dividir una cadena basándote en lo que está antes sin perder el(los) carácter(es) de división.
¿Qué coincide?
'$100'.match(/$\d+/)Los caracteres especiales necesitan escaparse con \ para coincidir literalmente:
$es un carácter especial (fin de cadena)- Para coincidir con un signo de dólar literal, escápalo:
\$
Caracteres comunes que requieren escape:
. * + ? ^ $ [ ] \ ( ) { } |Sin escapar, muchos caracteres especiales tienen significados de regex que pueden no ser lo que deseas.
¿Qué coincide?
'$100'.match(/(?<=\$)\d+/)El look-behind positivo (?<=\$) asegura que los dígitos estén precedidos por un signo de dólar:
(?<=\$): Look-behind para el signo de dólar\d+: Coincide con uno o más dígitos
Las aserciones look-behind no consumen caracteres; solo verifican lo que está antes. Esto es útil cuando quieres coincidir algo basándote en lo que lo precede sin incluir esa parte.
¿Qué coincide?
'<b>bold</b>'.match(/<b>(.*?)<\/b>/).slice(1)El patrón usa coincidencia perezosa con *?:
<b>: Coincide la etiqueta de apertura(.*?): Captura cualquier carácter (perezoso)</b>: Coincide la etiqueta de cierre
El ? después de * la hace perezosa, coincidiendo la menor cantidad de caracteres posible.
Sin ?, sería codicioso y coincidiría la mayor cantidad posible.
slice(1) devuelve solo el grupo capturado.
¿Qué coincide?
'😀 🙂'.match(/\p{Emoji}/gu)El flag u habilita:
- escapes de propiedades Unicode (
\p{...}) - manejo correcto de pares sustitutos
Sin u, los emoji y otros caracteres Unicode podrían no coincidir correctamente.
El patrón \p{Emoji} coincide con los caracteres que tienen la propiedad Unicode Emoji. En esta cadena, eso significa los dos pictogramas emoji.
Nota: los escapes de propiedades Unicode requieren el flag u.
¡Disculpas de antemano! 😈
¿Cuál contraseña coincide con este patrón?
/^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$/¡No escribas nada así en producción! 😅
Este patrón usa múltiples look‑ahead positivos para imponer:
- Al menos una letra mayúscula:
(?=.*[A-Z]) - Al menos una letra minúscula:
(?=.*[a-z]) - Al menos un dígito:
(?=.*\d) - Al menos un carácter especial:
(?=.*[!@#$%^&*]) - Longitud mínima de 8:
.{8,}
Los look‑ahead son perfectos para la validación de contraseñas porque pueden comprobar varios criterios sin consumir caracteres.
¿Cómo te fue? 🧐
Las expresiones regulares pueden ser una bestia de domar, pero son increíblemente poderosas una vez que le agarras el truco (y toda la sintaxis nueva). Sigue practicando y serás un maestro del RegEx en nada de tiempo! 🧙♂️
¿Buscas un descanso después de tanto RegEx?
Pftt, recuerda: ¡descanso después de las habilidades!
Visita mi gimnasio para aplastar más desafíos! 💪