Ir al contenido principal

Expresiones Regulares y pruebas en javascript

¿Qué es una expresión regular?
Una expresión regular es una cadena que contiene una combinación de caracteres normales y metacaracteres o metasecuencias especiales. Los caracteres normales coinciden por ellos mismos. Los metacaracteres y metasecuencias son caracteres o secuencias de caracteres que representan ideas como cantidad, posiciones o tipos de caracteres.
Regular Expression Pocket Reference 2nd Ed - Tony Stubblebine - O'Reilly

¿Para qué son útiles las expresiones regulares?
Las expresiones son especialmente útiles para validar información, por ejemplo en formularios de ingreso de datos. Por ejemplo para validar que se ingresó un número de teléfono, puedes usar la siguiente expresión regular.

/^([\+][0-9]{1,3}[ \.\-])?([\(]{1}[0-9]{2,6}[\)])?([0-9 \.\-\/]{3,20})?$/

Parecieran símbolos al azar, pero nada mas lejos de la realidad. Te muestro una tabla básica con los elementos usados para crear expresiones regulares.

Carácter Texto buscado
^ Principio de entrada o línea.
$ Fin de entrada o línea.
* El carácter anterior 0 o más veces.
+ El carácter anterior 1 o más veces.
? El carácter anterior una vez como máximo (es decir, indica que el carácter anterior es opcional).
. Cualquier carácter individual, salvo el de salto de línea.
x|y x o y.
{n} Exactamente n apariciones del carácter anterior.
{n,m} Como mínimo n y como máximo m apariciones del carácter anterior.
[abc] Cualquiera de los caracteres entre corchetes. Especifique un rango de caracteres con un guión (por ejemplo, [a-f] es equivalente a [abcdef]).
[^abc] Cualquier carácter que no esté entre corchetes. Especifique un rango de caracteres con un guión (por ejemplo, [^a-f] es equivalente a [^abcdef]).
\b Límite de palabra (como un espacio o un retorno de carro).
\B Cualquiera que no sea un límite de palabra.
\d Cualquier carácter de dígito. Equivalente a [0-9].
\D Cualquier carácter que no sea de dígito. Equivalente a [^0-9].
\f Salto de página.
\n Salto de línea.
\r Retorno de carro.
\s Cualquier carácter individual de espacio en blanco (espacios, tabulaciones, saltos de página o saltos de línea).
\S Cualquier carácter individual que no sea un espacio en blanco.
\t Tabulación.
\w Cualquier carácter alfanumérico, incluido el de subrayado. Equivalente a [A-Za-z0-9_].
\W Cualquier carácter que no sea alfanumérico. Equivalente a [^A-Za-z0-9_].
Mas información: http://www.regular-expressions.info/reference.html

Caso de ejemplo

Creemos una expresión regular para validar nombres de usuario, con las siguientes reglas:
  1. 1. Puede contener letras, números y los siguientes caracteres: ( _ guión bajo), ( . punto), ( - guión)
  2. 2. Debe iniciar con un caracter alfanumérico o ( _ guión bajo)
  3. 3. La cadena debe contener al menos una letra o número

Teniendo claro las reglas procederemos con la regla que me parece mas fácil, la número dos, así tendremos:

/^[\w]{1}$/

/^ simplemente nos indica el inicio de la expresión 
\w Cualquier caracter alfanumérico
{1}  Limita la expresión enterior a repetirse una sola vez exactamente
$/  Fin de la expresión
  

Esa expresión tal y como está nos restringe a una palabra con un solo caracter, pero si la combinamos con mas expresiones se convierte en un validador del primer caracter. Ahora tomemos la regla número 1, que también es fácil

/^[\w]{1}[0-9a-zA-Z_|\-|\.]$/
 
[0-9a-zA-Z_|\-|\.]  Esto es lo único que agregamos con respecto al anterior y lo veremos en detalle:
  [] no dice que será un grupo, 0-9 representa una secuencia en este caso todos los números entre 0 y 9 incluyendolos, a-z y A-Z  es análogo, \- es el caracter (- guión) que debe ser escapado por que un guión solitario tiene otro rol dentro de las expresiones regulares, igual con \.

Así que tenemos validado que nuestro primer caracter sea alfanumérico y que a continuación siga cualquier cantidad de caracteres alfanuméricos o los tres caracteres especificados en la regla. Sin embargo esta validación aun permite cadenas como _------- ó _.......... que claramente no son aceptables. Así llegamos a la última regla y para mí la mas complicada de realizar.

/^\w{1}([0-9a-zA-Z_|\-|\.]*[0-9a-zA-Z]+[0-9a-zA-Z_|\-|\.]*)$/
 
La idea que apliqué fue dividir la cadena después del primer caracter en tres partes:
[0-9a-zA-Z_|\-|\.]*  Esto nos dice lo mismo que en el paso dos excepto que el asterisco la hace una parte opcional es decir que se puede repetir 0 o muchas veces
 [0-9a-zA-Z]+  Parecido al anterior, excepto que no permite los caracteres _, -, ., y el + final nos dice que se debe repetir 1 o mas veces, haciendolo obligatorio
[0-9a-zA-Z_|\-|\.]* Igual que el primero 
  
Y con esto nos aseguramos la tercer regla.

Intuimos que funcionará pero no tenemos la certeza así que aplicaremos unas pruebas en javascript:

var test= {
    expresion : new RegExp(/^\w{1}([0-9a-zA-Z_|\-|\.]*[0-9a-zA-Z]+[0-9a-zA-Z_|\-|\.]*)$/),
    init: function(){
        var debenPasar = ['juan','_juan','juan_',
            'juan.carlos','juan_carlos','juan-carlos'];
        var noDebenPasar = ['-juan','.juan','------','_____','.....','_-----','_....','a_____','a......'];
        this.probar(debenPasar, true);
        this.probar(noDebenPasar, false);
    },
    probar : function(datos, resultado){
        for(var i=0; i<datos.length; i++){
            if(this.expresion.test(datos[i])!=resultado){
                console.log(datos[i]+' rompe la regla');
                return false;
            }
        }
        return true
    }
};
test.init();


Si tienen un caso que rompa la expresión regular, favor dejarla en los comentarios

Comentarios

  1. Hola, me parecio muy interesante el articulo. Estaba buscando precisamente esta validación y me sirvió de mucho. Felicidades y sigue adelante.
    Saludos

    ResponderEliminar
  2. Este comentario ha sido eliminado por el autor.

    ResponderEliminar

Publicar un comentario

Entradas populares de este blog

Enumerar filas en una consulta con MySQL

Supongamos que tenemos tablas con la estructura siguiente: documentos (iddocumento, nombre_documento, url_original, idtipo_documento, idproyecto) proyectos (idproyecto, nombre_proyecto, longitud, unidad_medida) tipo_documentos (idtipo_documento, descripcion_tipo_documento) Tenemos necesidad de hacer una consulta como la siguiente: "Enumerar todos los documentos en la base de datos agrupados por proyecto" Parece fácil, excepto por el término "enumerar", aquí tienes un truquito para que logres enumerar tus consultas: SELECT (@rownum:=@rownum+1) AS rownum, nombre_documento, descripcion_tipo_documento, nombre_proyecto FROM (SELECT @rownum:=0) r, documentos AS d INNER JOIN proyectos AS p ON d.idproyecto = p.idproyecto INNER JOIN tipo_documentos AS td ON d.idtipo_documento = td.idtipo_documento Pero que tal si te piden que enumeres los proyectos con sus correspondientes documentos?. Teniendo lo anterior es un poco mas sencillo SELECT IF(@fila=proyectos.idproyecto,

Tips y enlaces de la semana

json_encode y problemas con acentos. Según la documentación de la función json_encode , esta solo funciona con caracteres codificados en utf-8, así que si trabajamos con caracteres con otra codificación podemos convertirlos con la función utf8_encode. Asi: json_encode(utf8_encode($dato)); Si lo que queremos es pasar un arreglo a json, debemos pasar cada item del arreglo a utf8 y para esto usaremos la función array_map, quedando de la siguiente manera: json_encode(array_map("utf8_encode",$arreglo)); Esta función está disponible desde la versión 5.2 de PHP, asi que si usas una versión anterior intentalo con la versión de json_encode y json_decode para PHP4 Este archivo se usa de la siguiente forma: // create a new instance of Services_JSON require_once('JSON.php'); $json = new Services_JSON(); // convert a complex value to JSON notation $value = array(1, 2, ‘foo’); $output = $json->encode($value); print($output); // accept incoming POST data $input =

"Abrir carpeta contenedora" en Firefox y KDE 4.3.x lanza Cervisia

Este es un bug conocido desde hace algún tiempo, pero hay un truco que puede solucionarlo: Edita cervisia.desktop y kfmclient-dir.desktop localizado en /usr/share/applications/kde4 y agrega una linea con "OnlyShowIn=KDE;". Despues de actualizar "update-mime-cache" firefox usará dolphin. Mas información: https://bugzilla.mozilla.org/show_bug.cgi?id=266600 Actualización: El proceso al fin y al cabo le falta un paso mas. Cuando volvi a probar abrir un archivo desde la opción de "Abrir carpeta contenedora", me pidió que asociara el archivo a un programa, así que nada mas me tocó buscar donde se encuentra dolphin(/usr/bin/) y marcar la opción recordar asociación Actualización: En OpenSUSE 11.2 el problema fue solucionado.