Aprenda expresiones regulares con este curso gratuito

“Algunas personas, cuando se enfrentan a un problema, piensan 'Lo sé, usaré expresiones regulares'. Ahora ellos tienen dos problemas." -Jamie Zawinski

Para algunas personas, el uso de expresiones regulares puede ser un problema. Pero no tiene por qué ser un problema para ti. Este artículo es un curso completo sobre expresiones regulares.

1. Introducción

Las expresiones regulares, o simplemente RegEx, se usan en casi todos los lenguajes de programación para definir un patrón de búsqueda que se puede usar para buscar cosas en una cadena.

Desarrollé un curso de video completo y gratuito en Scrimba.com para enseñar los conceptos básicos de las expresiones regulares.

Este artículo contiene el curso en forma escrita. Pero si prefiere ver la versión en video con lecciones interactivas, puede consultarlo en Scrimba. Las secciones de este artículo corresponden a las secciones del curso Scimba.

Este curso sigue junto con el plan de estudios de RegEx en freeCodeCamp.org. Puede comprobarlo para conocer los desafíos de codificación y obtener un certificado.

Estas lecciones se centran en el uso de RegEx en JavaScript, pero los principios se aplican a muchos otros lenguajes de programación que puede optar por utilizar. Si aún no conoce JavaScript básico, podría ser útil que lo cubra un poco primero. También tengo un curso básico de JavaScript al que puedes acceder en Scrimba y en el canal de YouTube freeCodeCamp.org.

¡Entonces empecemos! Estarás salvando el día en poco tiempo. ?

2. Usando el método de prueba

Para hacer coincidir partes de cadenas usando RegEx, necesitamos crear patrones que le ayuden a hacer esa coincidencia. Podemos indicar que algo es un patrón RegEx colocando el patrón entre barras /, así /pattern-we-want-to-match/.

Veamos un ejemplo:

// We want to check the following sentencelet sentence = "The dog chased the cat."
// and this is the pattern we want to match.let regex = /the/

Observe cómo usamos /the/para indicar que estamos buscando "el" en nuestro sentence.

Podemos usar el test()método RegEx para saber si un patrón está presente en una cadena o no.

// String we want to testlet myString = "Hello, World!";
// Pattern we want to findlet myRegex = /Hello/;
// result is now truelet result = myRegex.test(myString);

3. Coincidir cadenas literales

Busquemos ahora a Wally.

let waldoIsHiding = "Somewhere Waldo is hiding in this text.";let waldoRegex = /Waldo/;
// test() returns true, so result is now also truelet result = waldoRegex.test(waldoIsHiding);

Tenga en cuenta que en este ejemplo waldoRegexdistingue entre mayúsculas y minúsculas, por lo que si escribiéramos /waldo/con una 'w' minúscula, nuestro resultsería falso.

4. Haga coincidir una cadena literal con diferentes posibilidades

RegEx también tiene un ORoperador que es |carácter.

let petString = "James has a pet cat.";
// We can now try to find if either of the words are in the sentencelet petRegex = /dog|cat|bird|fish/;
let result = petRegex.test(petString);

5. Ignorar mayúsculas y minúsculas al hacer coincidir

Hasta ahora, hemos analizado los patrones cuando importaba el caso de las letras. ¿Cómo podemos hacer que nuestros patrones de expresiones regulares no distingan entre mayúsculas y minúsculas?

Para ignorar el caso, podemos hacerlo agregando la ibandera al final de un patrón, así /some-pattern/i.

let myString = "freeCodeCamp";
// We ignore case by using 'i' flaglet fccRegex = /freecodecamp/i;
// result is truelet result = fccRegex.test(myString);

6. Extraer coincidencias

Cuando queremos extraer el valor coincidente, podemos usar el match()método.

let extractStr = "Extract the word 'coding' from this string.";
let codingRegex = /coding/;
let result = extractStr.match(codingRegex);
console.log(result);
// Terminal will show: // > ["coding"]

7. Encuentra más que la primera coincidencia

Ahora, cuando sabemos cómo extraer un valor y también es posible extraer varios valores usando la gbandera

let testStr = "Repeat, Repeat, Repeat";
let ourRegex = /Repeat/g;
testStr.match(ourRegex); // returns ["Repeat", "Repeat", "Repeat"]

También podemos combinar la gbandera con la ibandera, para extraer múltiples coincidencias e ignorar las mayúsculas y minúsculas.

let twinkleStar = "Twinkle, twinkle, little star";
let starRegex = /twinkle/ig;// writing /twinkle/gi would have the same result.
let result = twinkleStar.match(starRegex);
console.log(result);
// Terminal will show: // > ["Twinkle", "twinkle"]

8. Haga coincidir cualquier cosa con el período comodín

En RegEx .hay un carácter comodín que coincidiría con cualquier cosa.

let humStr = "I'll hum a song";
let hugStr = "Bear hug";
// Looks for anything with 3 characters beginning with 'hu'let huRegex = /hu./;
humStr.match(huRegex); // Returns ["hum"]
hugStr.match(huRegex); // Returns ["hug"]

9. Combina un solo personaje con múltiples posibilidades

Hacer coincidir cualquier carácter es bueno, pero ¿qué pasa si queremos restringir la coincidencia a un conjunto predefinido de caracteres? Podemos hacerlo usando []dentro de nuestra RegEx.

Si es así /b[aiu]g/, significa que podemos hacer coincidir 'bolsa', 'grande' y 'error'.

Si queremos extraer todas las vocales de una oración, así es como podemos hacerlo usando RegEx.

let quoteSample = "Beware of bugs in the above code; I have only proved it correct, not tried it.";
let vowelRegex = /[aeiou]/ig;
let result = quoteSample.match(vowelRegex);

10. Emparejar letras del alfabeto

Pero, ¿y si queremos hacer coincidir un rango de letras? Claro, hagámoslo.

let quoteSample = "The quick brown fox jumps over the lazy dog.";
// We can match all the letters from 'a' to 'z', ignoring casing. let alphabetRegex = /[a-z]/ig;
let result = quoteSample.match(alphabetRegex);

11. Emparejar números y letras del alfabeto

Las letras son buenas, pero ¿y si también queremos números?

let quoteSample = "Blueberry 3.141592653s are delicious.";
// match numbers between 2 and 6 (both inclusive), // and letters between 'h' and 's'. let myRegex = /[2-6h-s]/ig;
let result = quoteSample.match(myRegex);

12. Coincidencia de caracteres individuales no especificados

A veces es más fácil especificar personajes que no quieres ver. Estos se llaman 'Caracteres Negados' y en RegEx puede hacerlo usando ^.

let quoteSample = "3 blind mice.";
// Match everything that is not a number or a vowel. let myRegex = /[^0-9aeiou]/ig;
let result = quoteSample.match(myRegex);// Returns [" ", "b", "l", "n", "d", " ", "m", "c", "."]

13. Coincidir con los personajes que aparecen una o más veces

Si desea hacer coincidir un carácter que aparece una o más veces, puede usar +.

let difficultSpelling = "Mississippi";
let myRegex = /s+/g;
let result = difficultSpelling.match(myRegex);// Returns ["ss", "ss"]

14. Coincidir con caracteres que aparecen cero o más veces

También hay un *cuantificador de RegEx. Este coincide incluso con 0 apariciones de un personaje. ¿Por qué podría ser útil esto? La mayoría de las veces suele estar en combinación con otros personajes. Veamos un ejemplo.

let soccerWord = "gooooooooal!";
let gPhrase = "gut feeling";
let oPhrase = "over the moon";
// We are trying to match 'g', 'go', 'goo', 'gooo' and so on. let goRegex = /go*/;
soccerWord.match(goRegex); // Returns ["goooooooo"]
gPhrase.match(goRegex); // Returns ["g"]
oPhrase.match(goRegex); // Returns null

15. Encuentra personajes con combinación perezosa

A veces, sus coincidencias de patrones pueden tener más de un resultado. Por ejemplo, digamos que estoy buscando un patrón en una palabra titanicy mis valores coincidentes deben comenzar con una 't' y terminar con una 'i'. Mis posibles resultados son 'titani' y 'ti'.

Es por eso que RegEx tiene los conceptos de "Coincidencia codiciosa" y "Coincidencia perezosa".

Coincidencia codiciosa encuentra la coincidencia más larga posible de la cadena que se ajusta al patrón de RegEx, esta es una coincidencia de RegEx predeterminada:

let string = "titanic";
let regex = /t[a-z]*i/;
string.match(regex);// Returns ["titani"]

Lazy match encuentra la coincidencia más corta posible de la cadena que se ajusta al patrón RegEx y para usarla necesitamos usar ?:

let string = "titanic";
let regex = /t[a-z]*?i/;
string.match(regex);// Returns ["ti"]

16. Encuentra uno o más criminales en una cacería

Ahora echemos un vistazo a un desafío de RegEx. Necesitamos encontrar a todos los criminales ('C') en una multitud. Sabemos que siempre permanecen juntos y es necesario escribir una expresión regular que los encuentre.

let crowd = 'P1P2P3P4P5P6CCCP7P8P9';
let reCriminals = /./; // Change this line
let matchedCriminals = crowd.match(reCriminals);

Puedes encontrarme analizando la solución en este elenco de Scrimba.

17. Emparejar patrones de cuerdas iniciales

La expresión regular también le permite hacer coincidir patrones que están solo al principio de una cadena. Ya hemos hablado de ^crear un conjunto de negación. Podemos usar el mismo símbolo para encontrar una coincidencia solo al comienzo de una cadena.

let calAndRicky = "Cal and Ricky both like racing.";
// Match 'Cal' only if it's at the beginning of a string. let calRegex = /^Cal/;
let result = calRegex.test(calAndRicky); // Returns true
let rickyAndCal = "Ricky and Cal both like racing.";
let result = calRegex.test(rickyAndCal); // Returns false

18. Emparejar patrones de cuerdas finales

¿Qué hay de hacer coincidir un patrón al final de una cadena? Podemos usar $para eso.

let caboose = "The last car on a train is the caboose";
// Match 'caboose' if it's at the end of a string.let lastRegex = /caboose$/;
let result = lastRegex.test(caboose); // Returns true

19. Emparejar todas las letras y números

Anteriormente, en las partes 10 y 11, les mostré cómo podemos unir rangos de letras y números. Si le pidiera que escribiera una expresión regular que coincida con todas las letras y números e ignore sus casos, probablemente habría escrito algo así /[a-z0-9]/giy eso es exactamente correcto. Pero es demasiado largo.

RegEx tiene algo llamado 'Clases de caracteres abreviados ' , que es básicamente una forma abreviada de expresiones RegEx comunes. Para hacer coincidir todas las letras y números que podemos usar \wy también obtenemos un subrayado _coincidente como una bonificación.

let quoteSample = "The five boxing wizards jump quickly.";
// Same as /[a-z0-9_]/gi to match a-z (ignore case), 0-9 and _let alphabetRegexV2 = /\w/g;
// The length of all the characters in a string// excluding spaces and the period. let result = quoteSample.match(alphabetRegexV2).length;
// Returns 31

20. Empareja todo menos letras y números

Si queremos hacer lo contrario y hacer coincidir todo lo que no sea una letra o un número (también excluir el subrayado _), podemos usar\W

let quoteSample = "The five boxing wizards jump quickly.";
// Match spaces and the periodlet nonAlphabetRegex = /\W/g;
let result = quoteSample.match(nonAlphabetRegex).length;
// Returns 6

21. Emparejar todos los números

Ok, ¿qué pasa si solo quieres números? ¿Hay una clase de caracteres taquigráficos para eso? Claro que lo es \d.

let numString = "Your sandwich will be $5.00";
// Match all the numberslet numRegex = /\d/g;
let result = numString.match(numRegex).length; // Returns 3

22. Emparejar todos los que no sean números

¿Le gustaría lo contrario y combinar todos los no números? Utilizar\D

let numString = "Your sandwich will be $5.00";
// Match everything that is not a numberlet noNumRegex = /\D/g;
let result = numString.match(noNumRegex).length; // Returns 24

23. Restringir posibles nombres de usuario

¡Hasta aquí todo bien! Bien hecho por llegar tan lejos. La expresión regular puede ser complicada ya que no es la forma más fácil de leer para codificar. Veamos ahora un ejemplo muy real y creemos un validador de nombre de usuario. En este caso tienes 3 requisitos:

  • Si hay números, deben estar al final.
  • Las letras pueden ser minúsculas y mayúsculas.
  • Al menos dos caracteres. Los nombres de dos letras no pueden tener números.

Intente resolver esto por su cuenta y si le resulta difícil o simplemente desea verificar la respuesta, consulte mi solución.

24. Emparejar espacios en blanco

¿Podemos hacer coincidir todos los espacios en blanco? Por supuesto, también podemos usar una abreviatura para eso y es\s

let sample = "Whitespace is important in separating words";
// Match all the whitespaceslet countWhiteSpace = /\s/g;
let result = sample.match(countWhiteSpace);
// Returns [" ", " ", " ", " ", " "]

25. Emparejar caracteres que no sean espacios en blanco

¿Puedes adivinar cómo hacer coincidir todos los caracteres que no son espacios en blanco? ¡Bien hecho \S!

let sample = "Whitespace is important in separating words";
// Match all non-whitespace characterslet countWhiteSpace = /\S/g;
let result = sample.match(countWhiteSpace);

26. Especifique el número superior e inferior de coincidencias

Puede especificar el número inferior y superior de coincidencias de patrón con 'Especificadores de cantidad'. Se pueden usar con {}sintaxis, por ejemplo {3,6}, donde 3es el límite inferior y 6el límite superior que se debe emparejar.

let ohStr = "Ohhh no";
// We want to match 'Oh's that have 3-6 'h' characters in it. let ohRegex = /Oh{3,6} no/;
let result = ohRegex.test(ohStr); // Returns true

27. Especifique solo el número más bajo de coincidencias

Cuando queremos especificar solo el límite inferior, podemos hacerlo omitiendo el límite superior, por ejemplo, para hacer coincidir al menos tres caracteres que podamos escribir {3,}. Observe que todavía necesitamos una coma, incluso cuando no especificamos el límite superior.

let haStr = "Hazzzzah";
// Match a pattern that contains at least for 'z' characterslet haRegex = /z{4,}/;
let result = haRegex.test(haStr); // Returns true

28. Especifique el número exacto de coincidencias

En la sección anterior mencioné que necesitamos una coma {3,}cuando especificamos solo el límite inferior. El motivo es que cuando escribe {3}sin coma, significa que busca coincidir exactamente con 3 caracteres.

let timStr = "Timmmmber";
// let timRegex = /Tim{4}ber/;
let result = timRegex.test(timStr); // Returns true

29. Compruebe si hay todo o ninguno

Hay ocasiones en las que es posible que desee especificar la posible existencia de un personaje en su patrón. Cuando una letra o un número es opcional y lo usaríamos ?para eso.

// We want to match both British and American English spellings // of the word 'favourite'
let favWord_US = "favorite";let favWord_GB = "favourite";
// We match both 'favorite' and 'favourite' // by specifying that 'u' character is optionallet favRegex = /favou?rite/; // Change this line
let result1 = favRegex.test(favWord_US); // Returns truelet result2 = favRegex.test(favWord_GB); // Returns true

30. Lookahead positivo y negativo

Los " Lookaheads " son patrones que le dicen a su JS que mire hacia adelante para buscar patrones más adelante. Son útiles cuando intenta buscar varios patrones en las mismas cadenas. Hay 2 tipos de lookaheads: positivos y negativos.

La búsqueda anticipada positiva usa ?=sintaxis

let quit = "qu";
// We match 'q' only if it has 'u' after it. let quRegex= /q(?=u)/;
quit.match(quRegex); // Returns ["q"]

La búsqueda anticipada negativa usa ?!sintaxis

let noquit = "qt";
// We match 'q' only if there is no 'u' after it. let qRegex = /q(?!u)/;
noquit.match(qRegex); // Returns ["q"]

31. Reutilizar patrones mediante grupos de captura

Imaginemos que necesitamos capturar un patrón repetitivo.

let repeatStr = "regex regex";
// We want to match letters followed by space and then letterslet repeatRegex = /(\w+)\s(\w+)/;
repeatRegex.test(repeatStr); // Returns true

En lugar de repetir (\w+)al final, podemos decirle a RegEx que repita el patrón, usando \1. Entonces, lo mismo que el anterior se puede escribir nuevamente como:

let repeatStr = "regex regex";
let repeatRegex = /(\w+)\s\1)/;
repeatRegex.test(repeatStr); // Returns true

32. Utilice grupos de captura para buscar y reemplazar

Cuando encontramos una coincidencia, a veces es útil reemplazarla por otra. Podemos usar el replace()método para eso.

let wrongText = "The sky is silver.";
let silverRegex = /silver/;
wrongText.replace(silverRegex, "blue");
// Returns "The sky is blue."

33. Eliminar espacios en blanco del principio y del final

Aquí tienes un pequeño desafío. Escriba una expresión regular que elimine cualquier espacio en blanco alrededor de la cadena.

let hello = " Hello, World! ";
let wsRegex = /change/; // Change this line
let result = hello; // Change this line

Si te quedas atascado o simplemente quieres comprobar mi solución, no dudes en echar un vistazo al elenco de Scrimba donde resuelvo este desafío.

34. Conclusión

¡Felicidades! ¡Has terminado este curso! Si desea seguir aprendiendo más, no dude en consultar esta lista de reproducción de YouTube, que tiene muchos proyectos de JavaScript que puede crear.

¡Sigue aprendiendo y gracias por leer!

Ahora está listo para jugar al golf regex. ?