Expresiones Regulares
Clase 13 de 43 • Curso de Programación en Bash Shell
Contenido del curso
Clase 13 de 43 • Curso de Programación en Bash Shell
Contenido del curso
Cuando se solicita ingresar información través de un programa por parte del usuario que está utilizando el programa, independientemente el lenguaje que esté realizado; es importante considerar la validación de la información no solo en su tamaño sino también en los tipos de datos, formatos soportados lo cual nos permite asegurar la calidad de la información que recibimos, almacenamos y procesamos.
Dentro de este contexto en la programación bash para cumplir con este objetivo se utiliza expresiones regulares, las cuales son básicamente cadenas de caracteres que definen un patrón de búsqueda que se valida frente a una información específica para asegurar que cumple la validación definida.
Se necesita conocer ciertos criterios utilizados en las expresiones regulares que son los siguientes:
Tomando en cuenta estos criterios se realizará un programa que valida la siguiente información: Número de Identificación de un tamaño de 10 números. Ejemplo: 1717836520 País de Origen denotado por dos letras en un rango específico. Ejemplo: EC, CO, US Fecha de Nacimiento en el formato yyyyMMDD. Ejemplo: 20181222
Primero se definirá las expresiones regulares y se solicitará la información del usuario:
Luego se validará cada expresión regular comenzando con la identificación, para lo cual para cada validación se utilizará la sentencia condicional if y para comparar la expresión se debe utilizar el siguiente formato especial if [[ $variable =~ $expresionRegular ]] como se muestra a continuación.
Se realizará la ejecución de la aplicación con los dos escenarios el correcto y el incorrecto como se muestra a continuación:
Finalmente el código fuente lo pueden encontrar en el repositorio de GitHub en el branch 7.ValidarInformacion
Francisco Lopez Campos
Julio Cesar Garduño Romero
Kevin Castellano
Julio Cardenas
Jimmy Dominguez
Diego Ramirez
Sergy Lopez Moreno
Jose Suarez
Fredy Mendoza Vargas
Pablo Daniel
Nicolás Díaz
Gustavo Marín
Gilman Hernando Ortega Rozo
Sebastian CA
KEVIN FIGUEROA
Leobardo Manuel García Cruz
Julio Barrios
Sebastian CA
Reinaldo Mendoza
Miguel Angel Reyes Moreno
Jared Jafet Mendizabal
Luis Quiroz Prada
Hubert Ronald Mendoza Canales
Marcelo Roman
German Tellez Vanegas
Angel Leonardo Arévalo Suárez
Freddy Brau Lee Mamani Rivas
Andres Prieto
Mario Ernesto Alfaro Salinas
Angel Leonardo Arévalo Suárez
DAVID Pareja Arango
Cristian Orlando Rincon Bonilla
Ivan Acosta
Solo como recomendación, utilicen imágenes mas grandes
Coincido que para fines prácticos deberían hacerlo. Como solución puntual, en estos casos, podrías abrirla en una nueva pestaña para hacer zoom de forma más sencilla o hacer el "CTRL +" en la misma página. Lo comento solo como aporte para alguien que lo necesite.
Deberían usar campos de código como este
Beco (Alberto Alcocer) tiene un excelente curso de expresiones regulares.
Hay que tener cuidado con los [[ toca dejar un espacio obligatoriamente o si no da errores de command no found.
Cometi un error al llamar la variable de regex y la expresion daba to como valido
Totalmente de acuerdo validación de espacio netamente importante.
Especial cuidado con la sintaxis! Me paso igual a mí también!
Leyendo comentarios mas abajo, me percato que el REGEX de la fecha no es del todo correcta puesto que no valida escenarios de fechas no validos es decir, si nosotros ingresamos una fecha como 1999 21 35 quitando los espacios, nos la toma como valida. Por ello leyendo comentarios y viendo el aporte de un companero les anexo como quedaria con la validacion de fechas, supongo que ya con sentencias if podemos validar con un regex especial para validar para los meses con 30 dias y asi.
#! bin/bash #Ejercicio de Ejemplo uso Regex #Autor: Sergy Lopez regexNum='^[0-9]{10}$' #valida numeros de longitud 10 paisRegex='^EC|COL|US$' dateRegex='^(19|20)([0-9]{2})(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])$' #valida > echo "Expresiones Regulares" read -p "Ingresa un Id: " id read -p "Ingresa las Iniciales del Pais: " pais read -p "Ingresa una fecha yyyymmdd: " date #Validamos la informacion if [[ $id =~ $regexNum ]]; then echo "ID: $id valido" else echo "ID: $id invalido" fi if [[ $pais =~ $paisRegex ]]; then echo "Pais: $pais valido" else echo "Pais: $pais invalido" fi if [[ $date =~ $dateRegex ]]; then echo "Fecha: $date valida" else echo "Fecha: $date invalida" fi
Como haces para copiar una imagen y que me permita copiar el codigo??
Gracias por el aporte
la chuleta, el machete, el acordeon y el bandoneon! porque es este curso va bien como el tango
[]
xD
Hay que tener presente la sintaxis [[ $a =~ $aRegex ]] se deben respetar los espacios alrededor de "=~" para que funcione correctamente.
gracias, no me funcionaba y era por esos espacios
code:
#!/bin/bash #capturing user input and validating stuff on it #ID: can't have more than 10 number and can only be characters 0-9 #Country: can only be in a range of 2 letters (ex: CO, US, EC) is an specific range #Date of birht: can only be in format yyyyDDMM (ex: 20181222) #NOTE: regex = regular expression id_regex='^[0-9]{10}$' #^beggining $end country_regex='^EC|CO|US|MX$' # year month day birth_regex='^(19|20)([0-9]{2})(0[1-9]|1[1-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1])$' #the numbers before the [] mean a constant, so therefore in the case of (0[1-9]|1[1-2]) we have N1N2 and N1 can only be 0 or 1 and N2 can be a num from 1-9 if N1 = 0 or 1-2 if = 1 #2010/03/30 echo "" echo "¬------------------------¬" echo "Welcome!" echo "Before passing please enter the following information (mandatory)" echo "" read -p "ID: " u_id read -p "Country of origin [EC, CO, US, MX]: " u_country read -p "Birth date [yyyyMMDD]: " u_bdate echo "" #NOTE: The ~ is actually part of the operator =~ which performs a regular expression match of the string to its left to the extended regular expression on its right #id validation if [[ $u_id =~ $id_regex ]]; then echo -e "ID ($u_id) - status:\t\t\tAPPROVED" else echo -e "ID ($u_id) - status:\t\t\t\tDENIED (check format)" fi #country validation if [[ $u_country =~ $country_regex ]]; then echo -e "Country of origin ($u_country) - status:\t\tAPPROVED" else echo -e "Country of origin ($u_country) - status:\t\tDENIED (check format)" fi #birth date validation if [[ $u_bdate =~ $birth_regex ]]; then echo -e "Birth date ($u_bdate) - status:\t\t\tAPPROVED" else echo -e "Birth date ($u_bdate) - status:\t\t\tDENIED (check format)" fi echo ""
output:
¬------------------------¬ Welcome! Before passing please enter the following information (mandatory) ID: 1987345026 Country of origin [EC, CO, US, MX]: CO Birth date [yyyyMMDD]: 20010230 ID (1987345026) - status: APPROVED Country of origin (CO) - status: APPROVED Birth date (20010230) - status: APPROVED
Después de unos 192 intentos, finalmente quedó perfecto…
Como grabas la pantalla y la conviertes en gif ?? :o
La expresion regular referente a la fecha no funciona bien. Estuve investigando el por que de esto. Al definir un rango [1-12] en realidad estamos haciendo esto [1-2]. Las expresiones no entienden mas allá del rango [0-9]. Tambien que debemos agrupar los valores 19 y 20 en un parentesis para que se entienda que debe ejecutar primero esa busqueda y luego la siguiente. Si no lo hacemos estamos diciendo que ejecute la busqueda de solo un 19 o lo que sigue. Todo esto es según lo que he investigue y aprendi del curso de expresiones regulares. Dejo mi versión de al expresión referente a la fecha:
^(19|20)[0-9]{2}((0[1-9])|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1])$
Se puede hacer más precisa con los años pero no quise hacerla más larga. Pero creo que se puede entender lo que quiero decir.
Al final del curso voy a dejar algo así como un git rep para los que estén interesados en tener una wiki a la que acudir caundo necesitan ayuda
Las expresiones regulares son un tema que me llama mucho la atencion y se pueden aplicar en muchos si no en todos los lenguajes, evitan un conditional hell
Son una herramienta maravillosa, me han salvado de horas de trabajo en mi día a día como programador
Mi aporte:
Utilizen esta pagina para comprobar/armar sus expresiones regulares:
REGEXR
y aqui las expresiones que arme:
^\d{10}$
^(EC|CO|US)$
^(19\d{2}|[2-9]\d{3})(0[1-9]|1[0-2])([01][1-9]|[12]\d|3[01])$
El unico detalle con la fecha de nacimiento es que no valida biciestos ni la cantidad de dias en el mes por lo que expresiones como 19900230, 20010231 etc, son correctas
Adicional cambien \d por [[:digit:]] o [0-9] o no les funcionaran las expresiones, volvi a subir el aporte por ver ese error
en el if, ¿"=~" significa "igual a"?, porque para mi significa "diferente a"
El operador
=~
No tiene nombre de acuerdo a la documentación de Bash
Dicho operador está inspirado en Perl y la idea es comprobar que la expresión de la izquierda concuerda con el patrón de la derecha es decir si hace “match”
Fuente: Bash regex =~ operator
#!/bin/bash #Programa para ejemplificar como capturar la informacion del usuario y validarla utilizando expresiones regulares #Autor: Marcelo R. identificacionRegex='^[0-9]{10}$' paisRegex='^EC|COL|US$' #fechaNacimientoRegex='^19|20[0-8]{2}[1-12][1-31]$' fechaNacimientoRegex='^(19|20)([0-9]){2}(0[1-9]|10-2$' echo "Expresiones regulares" read -p "Ingresar una identificacion: " identificacion read -p "Ingresar las iniciales de un Pais [EC, COL, US]: " pais read -p "Ingresar la fecha de nacimiento [yyyyMMdd]: " fechaNacimiento #Validacion Identificacion if [[ $identificacion =~ $identificacionRegex ]]; then echo "Identificacion $identificacion valida" else echo "Identificacion $identificacion invalida" fi #Validacion Pais if [[ $pais =~ $paisRegex ]]; then echo "Pais $pais valida" else echo "Pais $pais invalido" fi #Validacion Fecha de Nacimiento if [[ $fechaNacimiento =~ $fechaNacimientoRegex ]]; then echo "Fecha Nacimiento $fechaNacimiento valida" else echo "Fecha Nacimiento $fechaNacimiento invalida" fi
En la regex del profe no se puede colocar 2009 como año o si? veo que solamente puede agregar digitos del 0 al 8
Cual es el link del repositorio de Github?
alguien que hizo el programa a mano no le paso que corria solo en el modo debugg
#!/bin/bash indentificationRegrex='^[0-9]{10}$' countryRegrex='^EC|COL|US$' birthdayRegrex='^19|20[0-8]{2}[1-12][1-31]$' echo "Expresiones regulares" read -p "Ingresar una identificacion:" identity read -p "Ingresar las iniciales de un país [EC, COL, US]:" country read -p "Ingresar la fecha de nacimiento [yyyyMMDD]:" birthday # Validación de identidad if [[ $identity =~ $indentificationRegrex ]]; then echo "Identificación $identity válida" else echo "Identificación $identity inválida" fi # Validación de país if [[ $country =~ $countryRegrex ]]; then echo "País $country válida" else echo "País $country inválida" fi # Validación de cumpleaños if [[ $birthday =~ $birthdayRegrex ]]; then echo "Fecha de nacimiento $birthday válida" else echo "Fecha de nacimiento $birthday inválida" fi
También lo deberías poder encontrar en el repode este curso
!/bin/bash
autor: mario alfaro
programa para validar expresiones regulares
valores predeterminados
idRegex='^[0-9]{10}$' paisRegex='^EC|COL|US$' nacimientoRegex='^(19|20)([0-9]{2})(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])$'
Datos del usuario
echo ">>>>>>>>> expreciones regulares <<<<<<<<<<<" read -p "ingresar un id: " identificacion read -p "ingresa las iniciales de tu pais [EC, COL, US]: " pais read -p "ingresa la fecha de nacimiento [yyyymmdd]: " fecha
validacion de id
if [[ $identificacion =~ $idRegex ]]; then echo "identificacion $identificacion valida " else echo "identificacion $identificacion invalida " fi
#validacion Pais
if [[ $pais =~ $paisRegex ]]; then echo "Pais $pais valido " else echo "Pais $pais invalido" fi
#Validacion Fecha Nacimiento if [[ $fechaNacimiento =~ $fechaNacimientoRegex ]]; then echo "Fecha Nacimiento $fechaNacimiento valida" else echo "Fecha Nacimiento $fechaNacimiento invalida" fi
Me funciono al fin, garcias a tu codigo.
En mi opinión, me ha gustado mucho este tema, sin embargo, pienso que para la expresión regular de la fecha de nacimiento hace falta cosas, por ejemplo, 19|20 se debería encerrar entre paréntesis, ya que de no hacerse, se puede interpretar como si fuera una fecha que empiece por el número 19 y solo 19 puede funcionar (algo que estaría mal ya que no representaría una fecha el número 19) o que sea 20 y todo lo demás que pueda resultar. Por otra parte, tanto para el mes como para el año los rangos no van a funcionar como se espera, debido a que [1-12] no aceptaría ni el 10 ni el 11 y tampoco el 12, del 1 al 9 funcionaría perfectamente. Mi propuesta es la siguiente:
fechaDeNacimiento='^(19|20)[0-9]{2}([1-9]|10|11|12)1-9?$'
Sé que no es perfecta, pero me ha gustado los resultados que ha arrojado. Aunque el curso no es de expresiones regulares, espero que pueda ayudar.
Mi solución al reto
Repositorio
#!/bin/bash # Program: # This program allows you to capture user input and validate it against a regular expression. # Validations: # - The user id must enter a number with size of 10 digits. # - The user origin must enter a valid country code. # - The user birth date must enter a valid date in the format yyyyMMDD. # Path: 2_interactive_scripts/3_regular_expressions.sh # Author: # Cristian Rincón # # How to run this script: # ./2_interactive_scripts/3_regular_expressions.sh user_id="" user_origin="" user_birth_date="" # Regular expression to validate user id. regex_user_id="^[0-9]{10}$" # Regular expression to validate user origin. regex_user_origin="^[A-Z]{2}$" # Regular expression to validate user birth date. regex_user_birth_date="^[0-9]{8}$" echo "RegEx program to validate user id, origin and birth date." read -p "Enter user id: " user_id read -p "Enter user origin: " user_origin read -p "Enter user birth date: " user_birth_date if [[ $user_id =~ $regex_user_id ]]; then echo "User id is valid." else echo "User id is not valid." fi if [[ $user_origin =~ $regex_user_origin ]]; then echo "User origin is valid." else echo "User origin is not valid." fi if [[ $user_birth_date =~ $regex_user_birth_date ]]; then echo "User birth date is valid." else echo "User birth date is not valid." fi
El uso de las expresiones regulares es una herramienta que claramente ayuda a tener más certeza de los datos que se están capturando por parte del usuario para asegurar la ejecución del código.