Expresiones Regulares: Te enseño lo básico con un solo ejemplo.
jjyepez
32743
Todos los desarrolladores profesionales deberían saber usar expresiones regulares. Con un solo ejemplo, te mostraré los elementos básicos de esta interesante herramienta… y un poco más.
Este es un tutorial muy narrativo, estilo “para Dummies” así que si tienes conocimientos avanzados en expresiones regulares, te invito a compartirlos con la comunidad a través de un nuevo tutorial un poco más avanzado 😉 …
.
Primero lo Primero
Primero lo Primero
¿Qué es una expresión regular?
Cuando hablamos de expresiones regulares, nos referimos (en términos muy generales) a patrones de coincidencia. Patrones que pueden usarse para comparar, extraer, remplazar o dividir segmentos de un texto particular, en otra cadena, texto largo o documento.
Por ejemplo, pudieras usar expresiones regulares para validar datos en un formulario: nombres de usuario, contraseñas, direcciones de correo, códigos postales, números telefónicos, etc, etc, etc
Son muchas las utilidades que tienen las regex, pero nos mantendremos en lo básico para lograr nuestro objetivo.
Para este tutorial usaremos JavaScript como lenguaje de programación. Ten en cuenta que dependiendo del contexto o lenguaje de programación que uses, los patrones pueden variar, pero en general, lo que aprenderás en este tutorial te servirá para la mayoría de los casos.
Normas generales
Para definir un patrón de expresión regular hay una cantidad de elementos y reglas que deben seguirse, pero las iremos viendo sobre la marcha.
La norma principal es que las expresiones regulares deben delimitarse con barras diagonales / … / en lugar de comillas o apóstrofescomo se hace con los literales alfanuméricos. No te preocupes, el lenguaje sabrá de que le hablas cuando identifique esta sintaxis.
Sintáxis básica de una Expresión Regular
/<patrón>/
Así pues cuando usemos una función que reciba como parámetro una expresión regular, en lugar de
funcion(“regex”)
o funcion(‘/regex/’)
… le pasaremos funcion(/regex/)
… al menos en JavaScript que es el lenguaje que nos interesa por el momento.
Los patrones
Los patrones regex están formados por elementos particulares, letras, símbolos, números o combinaciones de estos, que indican las condiciones que se deben cumplir en la cadena para considerarla una coincidencia (o válida en nuestro caso).
Los más comunes de estos elementos son … los corchetes [ ], los paréntesis ( ), las llaves { }, la barra invertida , el pipe | y los símbolos *, +, $, ^ y ? …. evidentemente hay muchos más, pero nos bastará con sólo algunos para empezar.
Pasaremos directo a ver un ejemplo práctico, y te explicaré cada uno de los elementos que nos vayamos encontrando, esto hará el tutorial más entretenido y dinámico.
Vamos con el ejemplo
Cédula de Identidad
En Venezuela, al documento nacional de identidad (DNI) se le llama cédula de identidad o simplemente cédula, y generalmente consiste en: una letra (V o E) que indica si se es venezolano o extranjero y un número entre 1 y 99 999 999, separados por un guión, como por ejemplo: V-15000123 ó E-82055055
Entonces, si quisiéramos validar el formato correcto de una cédula venezolana usaremos inicialmente este patrón (aunque hay varias formas de hacerlo):
/[VE]-[0123456789]{1,8}/
Este patrón significa -en un lenguaje natural- lo siguiente:
Para ser valida como cédula de identidad, la cadena suministrada debe:
- empezar por una letra que puede ser V ó E
- seguir con un guión simple
- continuar con números entre el 0 y 9 (mínimo 1 digito y 8 como máximo)
Aunque es bastante claro el significado del patrón, explicaré un poco más.
Los corchetes [ ] indican un conjunto de caracateres, un dominio (si hablamos de teoría de conjuntos), significa que sólo los caracteres de ese conjunto pueden usarse, y no otros.
Si no se especifica la cantidad de estos caracteres, se asume que sólo se refiere a una (1) posición, un sólo carácter del conjunto. En este ejemplo, o V o E … pero no las dos, y no puede omitirse.
Seguidamente vemos un guión. Cuando no colocamos corchetes [ ], ni otros símbolos de agrupación (que veremos luego), la presencia de un carácter significa literalmente ese carácter en esa precisa posición. Así pues en este caso, el guión sólo representa eso, un guión “-” luego de la letra V o E.
Luego vemos, de nuevo entre corchetes un conjunto de números. Ya sabemos que representan los valores individuales que se pueden usar, en este caso, cualquier número entre 0 y 9, que por cierto, podrían haber estado ordenados así [ 5432109876 ] y tendrían exactamente el mismo efecto. Incluso, pudiéramos usar una forma abreviada más cómoda, que es [ 0-9 ] … que indica el mismo rango de valores, de 0 a 9, y donde el guión separa el valor menor del mayor …
Nota: en este caso el guión tiene una función específica porque esta dentro de los corchetes y separa los dos valores.
Nota: en este caso el guión tiene una función específica porque esta dentro de los corchetes y separa los dos valores.
Antes vimos que si no se especifica la cantidad de posiciones o caracteres del conjunto que se esperan, por defecto sólo representa una posición. Pero en este ejemplo vemos que luego del conjunto definido por los segundos corchetes tenemos unos valores entre llaves.
Las llaves indican, cuantificadores de posiciones o caracteres permitidos. En este caso, entre 1 y 8 caracteres, que pueden ser cualquiera de los valores individuales del conjunto definido por los corchetes.
Finalmente, pudiéramos entonces rescribir este patrón RegExp como:
/[VE]-[0-9]{1,8}/
En JavaScript (ES5+) una forma simple de probar los patrones sería la siguiente:
const cedula = 'V-11122233'// --- cadena a probar
const regExp = newRegExp( /[VE]-[0-9]{1,8}/ ) // --- sin comillas
const resultado = regExp.test( cedula )
//--
console.log ( resultado ) // --- true = coincide, false = no-coincide
// código incluído a sugerencia de @danielpp95 .. ;)
Si no se cumple el patrón, la expresión devuelve falso o null, dependerá de la función o el método que se use. En nuestro caso usamos el método test de javascript para evaluar la coincidencia de una cadena con el patrón regex.
Hasta aquí ¿cómo vamos? … ¿bien? … pues seguimos.
A pesar de que ya pudiéramos decir que con este patrón nos basta para validar un número de cédula correctamente -y es así en realidad- seguiremos con este mismo ejemplo para ver muchos otros elementos interesantes de las RegExp.
Los modificadores o flags
Las expresiones regulares tienen tres modificadores (o flags) que se colocan al final del patrón, después de la barra delimitadora. Estos modificadores afectan el comportamiento del patrón según nuestra conveniencia. Son básicamente tres: i, gym. Pero por el momento sólo te hablaré del modificador i.
Al colocar i al final del patrón (luego de la barra delimitadora), le estamos indicando al método (test en este caso), que haga comparación insensible a mayúsculas y minúsculas. Así pues, considerará como váildos: v, V, e, yE en nuestro ejemplo, lo que es muy conveniente en ciertos casos.
Nuestra expresión regular quedaría así:
/[VE]-[0-9]{1,8}/i
Ahora digamos que en ciertas ocasiones no queremos exigir la presencia del carácter que indica la nacionalidad (V o E), ni el guión de separación. En otras palabras, que esa parte de la cadena sea considerada opcional. Que si vienen esté bien, y si no vienen, también esté bien.
Para eso necesitaremos un par de elementos nuevos. El signo ? … Y los paréntesis ( )
El signo ? dentro de un patrón RegExp indica (típicamente) que la presencia de un elemento es opcional, es decir, el carácter (o grupo) inmediatamente anterior a este signo, pudiera estar presente o no en la cadena, aún así sería dada por válida.
NOTA: El signo ? se parece un poco en su comportamiento al los signos * y + pero los dejaremos a un lado por el momento para no confundirnos.
Los paréntesis ( ), se usan básicamente para agrupar una parte del patrón y considerar a esa parte como un elemento individual.
Entonces, para lograr lo que nos interesa en este ejemplo, agruparemos los elementos del patrón que representan la nacionalidad, y los haremos opcionales obteniendo lo siguiente:
/([VE]-)?[0-9]{1,8}/i
Ya pudiéramos usar esta expresión regular para validar la mayoría de los casos que queremos: V-11111111, E-85000000, v-1, e-99999999, 85000000, 123123 pero aún hay varias cosas interesantes por ver.
Haz una pausa acá y revisa detenidamente esta expresión regular. Describe mentalmente o en voz alta, cada uno de los elementos que has aprendido, y no continúes hasta que hayas visto claramente el funcionamiento de cada elemento de este patrón. ¡Una vez que lo sabes, es genial!
Seguimos.
Haremos algunos ajustes más a nuestra expresión regular, para que no se nos escape nada.
Por defecto, la verificación de la expresión regular se hace en cualquier parte de la cadena … es como si le dijeras al programa, busca alguna coincidencia de este patrón en cualquier parte de la cadena o texto largo. Significa entonces que cadenas como: xxV-111111, hola5555555mundo ó v-555A, devolverían true para el método test ya que todas tienen un segmento que coincide con nuestro patrón.
Mucha atención acá, porque vamos a elevar un poco el nivel de complejidad.
Si testeamos la cadena xxV-11111 con el patrón
/([VE]-)?[0-9]{1,8}/i
, el resultado sería válido (true) porque a pesar de que el principio de la cadena es xx, todo el resto coincide perfectamente con nuestra expresión regular.
Es el momento de conocer un par de elementos nuevos, los signos: ^ y $.
Estos signos se usan típicamente al inicio y final del patrón respectivamente, pero a diferencia del modificador i, van por dentro de los delimitadores, así: / ^ …. /i o / … $ /i e indican al programa que busque específicamente las coincidencias específicamente al inicioo bien al final de la cadena (el signo ^ sirve para algo más pero nos quedaremos sólo con esta función por ahora).
Si existen coincidencias que no estén estrictamente al inicio de la cadena o al final, según le hemos indicado, entonces no las considerará válidas.
Así pues, mejoraremos nuestra expresión regular así:
/^([VE]-)?[0-9]{1,8}$/i
¿Genial cierto?
Pero veamos una a la vez.
Si sólo usamos ^ al inicio tendríamos:
/^([VE]-)?[0-9]{1,8}/i
De esta manera xxV-11111 ya no sería considerada válida, porque, a pesar de que una parte de la cadena coincide con nuestro patrón, ésta no estaría estrictamente al inicio como indica nuestra expresión regular.
De forma similar pasa si sólo usamos $ al final. Tendríamos:
/([VE]-)?[0-9]{1,8}$/i
Ahora v-555A ya no sería considerada válida, porque, a pesar de que una parte de la cadena (al inicio) coincide perfectamente con nuestro patrón, todavía tiene más caracteres posteriores a la coincidencia, por lo que no está ubicada estrictamente al final.
Así que al colocar ambos elementos como ya vimos antes:
/^([VE]-)?[0-9]{1,8}$/i
Estaríamos asegurándonos de que la cadena se considere válida sólo cuando la coincidencia sea total, y la cadena completa* desde el inicio hasta el final, coincida perfectamente con nuestra expresión regular.
Ya para terminar te hablaré de un elemento más: el signo de barra invertida \ o como se conoce también, el caracter de escape o backslash.
El signo de barra invertida \ sirve fundamentalmente para tres cosas:
La primera es para indicar que un carácter en particular debe ser tomado como un literal.
Por ejemplo el paréntesis -que como hemos visto sirve para definir un grupo en nuestra expresión regular- al estar precedido del carácter de la barra invertida \ ( se convierte en un literal exactamente como el guión que usamos antes en nuestro ejemplo, y ya no definirá un grupo.
Esto es muy útil para crear patrones de números telefónicos por ejemplo. Pero por ahora nos quedaremos sólo con la idea de que la barra invertida sirve como carácter de escape para indicar que algún carácter debe ser tomado como un literalen nuestra expresión regular.
El segundo uso de la barra invertida, es para introducir elementos particulares dentro de las expresiones regulares llamados caracteres escapados, como por ejemplo: \t que representa un tabulador, \n un fin de línea o \r retorno de carro, entre otros.
Y el tercer uso con el que haremos la última modificación a nuestra expresión regular, es indicar metacaracteres.
Los metacaracteres son elementos que abrevian o representan en sí mismos, patrones predefinidos. Son como atajos.
Con el fin de no extenderme mucho más, sólo veremos los dos (2) más comunes que son \w y \d.
El \w es equivalente al patrón [a-zA-z0-9_](sorpresa, dentro de los corchetes puedes usar varios rangos de valores sin necesidad de usar comas ni separadores), así, este segundo metacaracter, equivale al conjunto de caracteres formados por letras de la a a la z(minúsculas), letras de la A a la Z (mayúsculas), los dígitos del 0 al 9 y adicionalmente el signo de underscore (_).
El \d es equivalente al patrón [0-9] que ya conocemos, así que pudiéramos usar entonces \d en cualquier momento y el resultado sería exactamente el mismo.
Ya para terminar de refinar nuestra expresión regular, completa y mejorada, para validar la gran mayoría de posibilidades de números de cédula en Venezuela, quedaría así:
/^([VE]-)?\d{1,8}$/i
¿Qué te parece?
¡LISTO!
Ya puedes crear tus propias expresiones regulares, al menos las más comunes, recuerda que este tutorial es introductorio, “para Dummies”.
¡Esto ha sido sólo un abreboca!
¡Esto ha sido sólo un abreboca!
Puedes probar los ejemplos de este curso en este pen.
Hay mucho más que aprender de esta herramienta magnífica que está disponible prácticamente en todos los lenguajes de programación modernos, incluso en los sistemas operativos y editores de código. Pero esto ya será para un próximo tutorial.
Te invito a que nos compartas cómo sería el patron de expresión regular del DNI o Documento de Identificación de tu país, o si te animas, algún otro que se te ocurra usando lo que aprendiste en este tutorial, ¡anímate!
Como siempre, si te gustó o te pareció útil este contenido, haz clic a la manito en el título. bai! 🤓🤘
Escribe tu comentario
+ 2
Ordenar por:
Te dejo esta interesante expresión regular, un poco más avanzada … lo único nuevo que tiene es el uso del signo pipe | … que representa un OR… es decir, indica que puede darse una de dos o más alternativas de un segmento o patrón …
Este patrón particular, daría como válidas (o true) para las siguientes cadenas:
#abcd99
, abcd99
, #00a
, 00a
pero daría false (no coincidentes), las siguientes:
#ab0d
, #AB0099
, #5544xx
, 1234
¿Recuerdas, cuál es el elemento que habría que agregarle a esta expresión regular para que también diera como válido a
#AB0
0 comentarios:
Publicar un comentario