
Hoy en la Buhardilla vamos a ver que son y como podemos usar las expresiones regulares o (regex, por sus siglas en inglés). Seguro que en muchas ocasiones te has encontrado en la situación de que tienes que buscar o manipular texto de una gran variedad de datos, pero resulta que una misma definición está escrita de distintas maneras (como por ejemplo que la primera letra esté escrita en mayúscula o minúscula, o que los nombres compuestos estén con un guion o separados por un espacio, por poner algún ejemplo). Cuando el volumen de datos es grande, tener que comprobar todas las posibles variaciones es una tarea casi imposible. En estas cosas es cuando las regex brillan por su funcionalidad. Las expresiones regulares utilizan una secuencia de caracteres para definir un patrón de texto a buscar, lo que permite a los programas reconocer una gran variedad de combinaciones posibles en la misma iteración. En esta entrada veremos las secuencias más importantes y como aplicarlas para poder encontrar cualquier texto en cualquier lugar. ¡Sin más dilación empecemos!!!
Las expresiones regulares (también conocidas como regex) son una secuencia de caracteres que nos permiten buscar patrones específicos en cadenas de texto. Son una gran herramienta que se utiliza en muchos lenguajes de programación y editores de texto para realizar búsquedas y reemplazos, verificar entradas de datos, extraer información y mucho más. Lo bueno es que una vez entendido su funcionamiento este es prácticamente el mismo en todos los lenguajes, así que no tendremos que aprenderlo una y otra vez. La principal característica es que dota de significados especiales a un conjunto de caracteres para poder realizar las operaciones y combinaciones oportunas.
| Función | Descripción | Ejemplo |
| ^ | coincide con el inicio de la línea | ^hola :– «hola mundo» (coincide) – «mundo hola» (no coincide) |
| $ | coincide con el final de la línea | mundo$ : – hola mundo» (coincide) – «mundo hola» (no coincide) |
| . | coincide con cualquier carácter individual | a.b :– «aeb» (coincide) – «aob» (coincide) – «ab» (no coincide) |
| + | coincide con la repetición de 1 o más caracteres | a+ : – «a» (coincide) – «aa» (coincide) – «aaa» (coincide) – «b» (no coincide) |
| * | coincide con la repetición de 0 o más caracteres | a* : – «» (coincide) – «a» (coincide) – «aa» (coincide) – «b» (coincide) |
| ? | hace que la repetición anterior sea opcional | a? : – «» (coincide) – «a» (coincide) – «aa» (no coincide) – «b» (coincide) |
| | | significa «o» | hola|mundo :– «hola» (coincide) – «mundo» (coincide) – «adiós» (no coincide) |
| – | Implica un rango | [a-z] : – cualquier valor comprendido entre la «a» a la «z». |
| [ ] | indican un conjunto de caracteres | [aeiou] coincide con cualquier cadena que contenga una vocal. Por ejemplo, «a» o «e». |
| [^] | Implica la negación de lo contenido en los corchetes | [^aeiou] coincide con cualquier cadena que no contenga una vocal. Por ejemplo, «b» o «n» |
| {n} | coincide con la repetición exacta de un carácter n veces | a{3} coincide con «aaa» |
| {n,} | coincide con la repetición de un carácter al menos n veces | a{3,} coincide con «aaa», «aaaa», |
| {n,m} | coincide con la repetición de un carácter al menos n veces y como máximo m veces | a{2,4} coincide con «aa», «aaa» y «aaaa» |
| \w | representar cualquier carácter alfanumérico | Por ejemplo, «hola123» o «abcdef» |
| \W | cualquier carácter que no sea alfanumérico | Por ejemplo, «!@#$» o «¿?» |
| \d | cualquier carácter que sea numérico | «123» (coincide) «456» (coincide) «abc» (no coincide) |
| (?=) | coincide si a continuación aparece el patrón definido después del igual | Por ejemplo, a(?=b) coincide con «a» solo si está seguido de una «b». Como podría ser «ab» o «abc». |
| (?!) | coincide si no está seguido de una determinada expresión regular | Por ejemplo, a(?!b) coincide con «a» solo si no está seguido de una «b». Como podría ser «ac» o «año» |
Las funciones anteriores permiten realizar la búsqueda de patrones sencillos. No obstante, si lo que queremos es filtrar con patrones más complejos lo mostrada anteriormente, puede que no sea suficiente. Para estas situaciones contamos con funcionalidades especiales como el anidamiento y las capturas. Que permiten usar las funciones descritas anteriormente de manera combinada.
- Anidamiento: se trata de usar paréntesis para agrupar partes de una expresión regular y tratarlas como una unidad. Por ejemplo, ((ab)?c)?d coincide con «d», «cd», «abcd» o «bcd».
- Capturas: Las capturas son una característica poderosa de las expresiones regulares que te permiten extraer y trabajar con subcadenas de texto coincidentes. Para crear una captura, se utilizan paréntesis alrededor del patrón de búsqueda deseado. Cada par de paréntesis crea un grupo de captura, numerados secuencialmente a partir de 1.
- Por ejemplo, si tenemos la expresión regular
(\w+)@(\w+)\.(\w+)y la aplicamos sobre un correo electrónico, podemos utilizar los grupos de captura para extraer el nombre de usuario (1), el nombre de dominio (2) y el sufijo del dominio de una dirección de correo electrónico (3). Otro ejemplo sería el caso(\d{4})-(\d{2})-(\d{2})coincide con cualquier cadena que contenga una fecha en el formato «AAAA-MM-DD». Los paréntesis crean tres grupos de captura.
- Por ejemplo, si tenemos la expresión regular
En las capturas también podemos utilizar las referencias posteriores para referenciarlos más tarde, esta funcionalidad se la conoce como backreferences y se identifican con \1, \2, etc. Las backreferences se utilizan para buscar coincidencias basadas en las capturas anteriores. Por ejemplo, si tenemos la expresión regular (\w+), podemos utilizar la backreference \1 para buscar coincidencias con la primera captura. Esto significa que la expresión regular buscará coincidencias con la misma cadena de texto que se capturó en la primera parte de la expresión regular. Por ejemplo, (\w+)\1 coincide con una palabra formada por dos veces el mismo carácter, como «papa» o «bobo». En el caso de números podríamos utilizar (\d{3})-\1 coincide con cualquier cadena que contenga un número de tres dígitos seguido de un guion y luego el mismo número.
Finalmente, también podemos usar los grupos para aplicar sustituciones. Los grupos de captura pueden utilizarse para realizar sustituciones de texto. Una vez que tenemos la información capturada en los distintos grupos la podemos transformar utilizando distintas funciones del lenguaje de programación deseado. De esta forma vamos a poder tener la información capturada en el formato u orden deseado. Por ejemplo, si tenemos la cadena de texto «juan.perez@ejemplo.com», podemos utilizar la expresión regular para sustituir la dirección de correo electrónico por «Juan_Perez».
En este punto es importante destacar que según su modo de búsqueda, las regex se pueden clasificar en expresiones regulares greedy y lazy.
- Las expresiones regulares greedy intentan coincidir con la mayor cantidad de texto posible, mientras que las expresiones regulares lazy intentan coincidir con la menor cantidad de texto posible. Por ejemplo:
- La expresión regular
a*es greedy y buscará coincidencias con la mayor cantidad de «a» posible. Por ejemplo, si tenemos la cadena de texto «aaaa», la expresión regulara*buscará coincidencias con toda la cadena de texto. - La expresión regular
a*?es lazy y buscará coincidencias con la menor cantidad de «a» posible. Por ejemplo, si tenemos la cadena de texto «aaaa», la expresión regulara*?buscará coincidencias con solo un «a».
- La expresión regular
También cabe destacar que el orden en que se ejecuten las expresiones va a tener un impacto considerable en la forma en que se procesan las coincidencias. Es por esta razón que siempre se tiene que pensar muy bien el texto o función que se quiere buscar y siempre comprobar que las expresiones que hemos definido funcionan correctamente para el propósito que queremos.
Con esto hemos visto como empezar a trabajar con las expresiones regulares y poder así realizar búsquedas mucho más afectivas y versátiles. No obstante, es importante remarcar que a pesar de que les regex pueden tener una gran utilidad, su uso excesivo puede llevar a expresiones regulares, complicadas y difíciles de entender. Por esta razón, es importante, trata de utilizar siempre las capturas de forma clara y concisa para mejorar la legibilidad y el mantenimiento de las expresiones regulares. Espero que con lo expuesto en esta entrada le perdáis el miedo y así empezar a utilizar esta herramienta tan potente.
¡Saludos y hasta la próxima aventura!!!