VoidWyrm

Tu privacidad es importante para nosotros.

Este sitio web utiliza cookies propias y de terceros para analizar tu navegación con fines estadísticos, de personalización y publicitarios, incluido el mostrarte publicidad personalizada a partir de un perfil elaborado en base a tu navegación. Al hacer clic en "Aceptar cookies", estarás dando tu consentimiento para esta actividad. Puedes encontrar más información en el apartado Privacidad y cookies.

VoidWyrm

8 funciones para la validación de formularios con expresiones regulares

27 de enero de 2015

+5.1K5

Si eres desarrollador web y necesitas validar tus formularios, aquí puedes encontrar unas buenas funciones para comprobar números, cadenas de texto, direcciones de correo electrónico, direcciones web (URL), códigos postales, NIF o NIE, CIF y números de teléfono.

8 funciones para la validación de formularios con expresiones regulares

Una de las situaciones más comunes en el desarrollo de un formulario web se da en el momento de realizar la validación de los datos del mismo. Nombre, apellidos, dirección o población son campos que no requieren de mucha validación, puesto que, salvo necesidades mayores, suele bastar con comprobar si fueron o no fueron introducidos por el usuario.

¿Pero qué ocurre con datos como una dirección de correo electrónico, una dirección web, un número de teléfono, el código postal de una dirección o el NIF de una persona? La estructura de estos campos es mucho más específica y compleja, ya que no se trata de simples cadenas de caracteres, sino que su estructura obedece a unas reglas y patrones determinados.

Pongamos algunos ejemplos. El número de teléfono, siempre que se trate de un móvil, debe ser un número de nueve dígitos y que comience por 6 o por 7. En caso de que sea un teléfono fijo, deberá comenzar por 8 o por 9. Por su parte, el número de identificación fiscal (NIF) de una persona debe estar formado por ocho dígitos seguidos de una letra (caracter de control) que, además, no puede ser arbitraria, sino que se obtiene realizando una serie de operaciones matemáticas con los ocho dígitos anteriores.

Pues bien, para comprobar la validez este tipo de datos, tarea que no suele ser precisamente sencilla para la mayoría de desarrolladores, disponemos de una maravillosa herramienta de los lenguajes de programación: las expresiones regulares. Según la Wikipedia, una expresión regular es una secuencia de caracteres que forma un patrón de búsqueda, principalmente utilizada para la búsqueda de patrones de cadenas de caracteres u operaciones de sustituciones.

Esta entrada no está dedicada a entrar en detalles sobre las expresiones regulares o su sintáxis. Quien quiera conocer más a fondo este tema puede encontrar mucha información al respecto en la red. El objetivo de este artículo es compartir con los demás varias funciones para la validación de algunos de los campos más típicos que podemos encontrar en un formulario web.

En concreto, las funciones que hemos desarrollado permiten la validación de los siguientes tipos de datos:

Validación de un número

La siguiente función puede ser utilizada para validar un número entero mayor o igual que cero. Esta función recibe dos parámetros: el valor que se comprobará y un parámetro booleano para indicar si el cero será o no considerado como un número válido.

function es_numero($numero, $cero_valido = false) {
	if (!$cero_valido) $re = '/^[1-9]+[0-9]*$/';   // {1,...,n}
	else $re = '/^(0|([1-9]+[0-9]*))$/';           // {0,...,n}
	
	return (preg_match($re, $numero));
}

Validación de una cadena de texto

Para comprobar si un campo está formado únicamente por letras de nuestro alfabeto, podemos utilizar la función que se muestra a continuación. Como se puede observar, además de los caracter alfabéticos típicos se ha añadido la letra 'Ñ', tanto en mayúscula como en minúscula, ya que se trata de un caracter especial y no está incluido en el conjunto anterior.

function es_alfabetico($c) {
	$re = '/^[a-zA-ZñÑ]+$/';
	
	return (preg_match($re, $c));
}

Validación de una dirección de correo electrónico

Una de las expresiones regulares que más quebraderos de cabeza ocasiona a los desarrolladores es la que permite verificar si una dirección de correo electrónico es válida. Para su desarrollo, hemos empleado dos expresiones regulares. La primera de ellas está extraída de jQuery Validation Plugin y prácticamente funciona por sí sola. Sin embargo, la hemos complementado con una segunda expresión regular que verifica la longitud del dominio de mayor nivel (TLD), ya que solo con la primera se considerarían válidas las direcciones de correo electrónico del tipo root@localhost.

function email_valido($email) {
	$email = strtolower($email);

	$re1 = '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/i';
	$re2 = '/^.+@.+\.[a-z]{2,4}$/i';

	return (preg_match($re1, $email) && preg_match($re2, $email));
}

Validación de una dirección web (URL)

Al igual que en la función anterior, la expresión regular utilizada para la validación de una dirección web ha sido extraída de jQuery Validation Plugin. Se trata de una expresión regular muy extensa, pero teniendo en cuentra su procedencia y los resultados de las pruebas realizadas, podemos afirmar que estamos muy satisfechos con su funcionamiento. Acepta los protocolos HTTP, HTTPS, FTP y SFTP.

function url_valido($url) {
	$re = '/^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\x{00A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}])|(%[\da-f]{2})|[!\$&\'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\x{00A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}])|(([a-z]|\d|[\x{00A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}])([a-z]|\d|-|\.|_|~|[\x{00A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}])*([a-z]|\d|[\x{00A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}])))\.)+(([a-z]|[\x{00A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}])|(([a-z]|[\x{00A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}])([a-z]|\d|-|\.|_|~|[\x{00A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}])*([a-z]|[\x{00A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\x{00A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}])|(%[\da-f]{2})|[!\$&\'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\x{00A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}])|(%[\da-f]{2})|[!\$&\'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\x{00A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}])|(%[\da-f]{2})|[!\$&\'\(\)\*\+,;=]|:|@)|[\x{E000}-\x{F8FF}]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\x{00A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}])|(%[\da-f]{2})|[!\$&\'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/ui';
	
	return (preg_match($re, $url));
}

Validación de números de teléfono

Para la validación de números de teléfono vamos a utilizar tres funciones: una para validar teléfonos fijos, otra para validar teléfonos móviles y otra para validar cualquier de ellos, sin tener en cuenta si se trata de un fijo o un móvil.

/*****************************/
/*       Teléfono fijo       */
/*****************************/

function fijo_valido($n) {
	$re = '/^(8|9)[0-9]{8}$/';
	
	return (preg_match($re, $n));
}

/******************************/
/*       Teléfono móvil       */
/******************************/

function movil_valido($n) {
	$re = '/^(6|7)[0-9]{8}$/';
	
	return (preg_match($re, $n));
}

/*************************************/
/*       Teléfono fijo o móvil       */
/*************************************/

function telefono_valido($n) {
	return (fijo_valido($n) || movil_valido($n));
}

Validación de un código postal

Para la validación de un código postal (de España) podemos utilizar la siguiente función, que comprueba si se trata de una cadena formada únicamente por dígitos y comienza por alguno de los códigos correspondientes a las provincias de nuestro país (desde '01' hasta '52').

function cp_valido($cp) {
	$re = '/^(0[1-9]|[1-4][0-9]|5[0-2])[0-9]{3}$/';
	
	return (preg_match($re, $cp));
}

Validación de un NIF o NIE

La validación de un número de identificación fiscal (NIF) o de un número de identidad de extranjero (NIE) es un poco más complicada, ya que, además de verificar si el patrón de la cadena es válido, hay que comprobar si el dígito de control es correcto. Puedes encontrar más información en la Wikipedia.

Muchas gracias @Julia por la corrección.

function nif_valido($nif) {
	$nif = strtoupper($nif);
	
	$nifRegEx = '/^[0-9]{8}[A-Z]$/i';
	$nieRegEx = '/^[XYZ][0-9]{7}[A-Z]$/i';
	
	$letras = "TRWAGMYFPDXBNJZSQVHLCKE";
	
	if (preg_match($nifRegEx, $nif)) return ($letras[(substr($nif, 0, 8) % 23)] == $nif[8]);
	else if (preg_match($nieRegEx, $nif)) {
		if ($nif[0] == "X") $nif[0] = "0";
		else if ($nif[0] == "Y") $nif[0] = "1";
		else if ($nif[0] == "Z") $nif[0] = "2";

		return ($letras[(substr($nif, 0, 8) % 23)] == $nif[8]);
	}
	else return false;
}

Validación de un CIF

Para finalizar, hemos incluido una función para comprobar si un código de identificación fiscal (CIF) es válido. De todas las funciones de validación incluidas en esta entrada, ésta es sin duda la más compleja, debido a la estructura de este campo. En la Wikipedia se puede encontrar más información sobre la estructura del CIF.

function cif_valido($cif) {
	$cif = strtoupper($cif);
	
	$cifRegEx1 = '/^[ABEH][0-9]{8}$/i';
	$cifRegEx2 = '/^[KPQS][0-9]{7}[A-J]$/i';
	$cifRegEx3 = '/^[CDFGJLMNRUVW][0-9]{7}[0-9A-J]$/i';
	
	if (preg_match($cifRegEx1, $cif) || preg_match($cifRegEx2, $cif) || preg_match($cifRegEx3, $cif)) {
		$control = $cif[strlen($cif) - 1];
		$suma_A = 0;
		$suma_B = 0;
		
		for ($i = 1; $i < 8; $i++) {
			if ($i % 2 == 0) $suma_A += intval($cif[$i]);
			else {
				$t = (intval($cif[$i]) * 2);
				$p = 0;
				
				for ($j = 0; $j < strlen($t); $j++) {
					$p += substr($t, $j, 1);
				}
				$suma_B += $p;
			}
		}
		
		$suma_C = (intval($suma_A + $suma_B)) . "";
		$suma_D = (10 - intval($suma_C[strlen($suma_C) - 1])) % 10;
		
		$letras = "JABCDEFGHI";
		
		if ($control >= "0" && $control <= "9") return ($control == $suma_D);
		else return (strtoupper($control) == $letras[$suma_D]);
	}
	else return false;
}

Todas las expresiones regulares anteriores están escritas en PHP. Si en tu sitio web realizas una doble verificación, tanto desde el lado del cliente (con JavaScript), como del lado del servidor (con PHP); es posible que te interese convertir estas funciones y expresiones regulares a JavaScript. Se trata de una tarea sencilla y puedes encontrar información sobre cómo hacerlo en Internet.

No obstante, aquí dejo una función de ejemplo para la validación de una dirección de correo electrónico con JavaScript:

function email_valido(email) {
	email = email.toLowerCase();
	
	var emailRegEx1 = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/i;
	var emailRegEx2 = /^.+@.+\.[a-z]{2,4}$/i;
	
	return (emailRegEx1.test(email) && emailRegEx2.test(email));
}

Espero que te sea de gran utilidad. Si te apetece dar tu opinión, puedes utilizar el sistema de comentarios que acabamos de incorporar al blog.

Si te ha gustado esta entrada y quieres apoyarme, puedes invitarme a un café:

5 comentarios

1

Álvaro

25 de septiembre de 2015 a las 12:22 h.25-sep-2015

Hola, me gustaría saber si podrías pasarme los métodos cif_vaido y nif_valido a JavaScript, ya que yo lo he intentado y Suma_B en php me da como resultado 2 y en JavaScript 0, es decir, que algo no está haciendo bien.

Lo he estado probando con el CIF P0200100F y A58818501.

ResponderChrome 45.0.2454.99Windows 7

2

VoidWyrm

25 de septiembre de 2015 a las 12:43 h.25-sep-2015

Aquí tienes @Álvaro:


function cif_valido(cif) {
	cif = cif.toUpperCase();
	var cifRegEx1 = /^[ABEH][0-9]{8}$/i;
	var cifRegEx2 = /^[KPQS][0-9]{7}[A-J]$/i;
	var cifRegEx3 = /^[CDFGJLMNRUVW][0-9]{7}[0-9A-J]$/i;

	if (cifRegEx1.test(cif) || cifRegEx2.test(cif) || cifRegEx3.test(cif)) {
		var control = cif.charAt(cif.length - 1);
		var suma_A = 0;
		var suma_B = 0;

		for (var i = 1; i < 8; i++) {
			if (i % 2 == 0) suma_A += parseInt(cif.charAt(i));
			else {
				var t = (cif.charAt(i) * 2) + "";
				var p = 0;

				for (var j = 0; j < t.length; j++) {
					p += parseInt(t.charAt(j));
				}

				suma_B += p;
			}
		}

		var suma_C = (suma_A + suma_B) + "";
		var suma_D = (10 - parseInt(suma_C.charAt(suma_C.length - 1))) % 10;
		var letras = "JABCDEFGHI";

		if (control >= "0" && control <= "9") return (control == suma_D);
		else return (control == letras.charAt(suma_D));
	}
	else return false;
}

console.log(cif_valido("P0200100F"));
console.log(cif_valido("A58818501"));

ResponderFirefox 40.0Windows 7

3

Álvaro

25 de septiembre de 2015 a las 13:28 h.25-sep-2015

@Antonio: Muchísimas gracias. Ahora me va perfecto.

ResponderChrome 45.0.2454.99Windows 7

4

Julia

3 de diciembre de 2015 a las 12:49 h.3-dic-2015

La función que valida el NIE no es correcta.

He hecho estos cambios para que funcione correctamente


function nif_valido($nif) {
	$nif = strtoupper($nif);
	$nifRegEx = '/^[0-9]{8}[A-Z]$/i';
	$nieRegEx = '/^[KLMXYZ][0-9]{7}[A-Z]$/i';
	$letras = "TRWAGMYFPDXBNJZSQVHLCKE";

	if (preg_match($nifRegEx, $nif)) return ($letras[(substr($nif, 0, 8) % 23)] == $nif[8]);
	else if (preg_match($nieRegEx, $nif))
	{/**
		Los NIE's de extranjeros residentes en España tienen una letra (X, Y, Z), 7 números y dígito de control.
		Para el cálculo del dígito de control se sustituye:
		X =0
		Y =1
		Z = 2
		y se aplica el mismo algoritmo que para el NIF.*/

		$r = str_replace(array('X', 'Y', 'Z'), array(0, 1, 2), $nif);
		//echo "letra:". $letras[(substr($r, 0, 8) % 23)]."y nif[8]=".$nif[8]."";

		return ($letras[(substr($r, 0, 8) % 23)] == $nif[8]);
	}
	else return false;
}

ResponderFirefox 42.0Windows 7

5

VoidWyrm

3 de diciembre de 2015 a las 17:59 h.3-dic-2015

@Julia: Pues tienes razón. No sé de donde saqué en su momento esa información, pero está claro que la función no validaba correctamente los NIE.

Ya está corregida la función del NIF/NIE.

Muchas gracias Julia.

ResponderFirefox 42.0Windows 7

Deja tu comentario

Puedes utilizar el siguiente formulario para aportar tu opinión o contestar a otras personas. Por favor, escribe con educación y respeto hacia los demás y no olvides revisar la ortografía. Si tu comentario es muy extenso, puedes separar el texto en varios párrafos.

  • Introduce tu nombre. No temas, no tengo un Death Note.
  • Introduce tu correo electrónico. No se compartirá con nadie.

Acepto el aviso legal y la política de privacidad de este sitio web.