INICIO

EXPRESIONES REGULARES EN PHP

Vamos a hablar de expresiones regulares.

A todos los que se inician en el mundo de las expresiones regulares se les pone cara de susto.

Parecen feas, no tienen sentido, son desordenadas, caóticas, incomprensiblemente misteriosas y misteriosamente mágicas.

Pero eso no puede ser.

En esta vida no hay nada más fácil que las expresiones regulares.

Te voy a explicar desde el primer punto hasta la última coma lo que es una expresión regular.

¿Qué es una expresión regular?

Una expresión regular es un patrón que satisface (cumple, verifica) ciertas condiciones sobre una cadena de texto.

Todas las cadenas de texto que satisfacen esas condiciones, verifican el patrón.

¿Qué patrón tienen por ejemplo las cadenas PATO y ALMENDRA?

Pues que ambas cadenas de texto tienen todos sus caracteres en mayúsculas.

La cadena ASTROnauTA no tiene ese patrón porque no tiene todos sus caracteres en mayúsculas.

¿Para qué sirve una expresión regular?

Imagina que yo tengo un formulario donde un usuario escribe su correo electrónico.

En teoría, el usuario es buena gente y lo hace.

Pero también hay mucho melón suelto que podría no necesariamente escribir su correo electrónico.

Yo necesito saber si lo que el usuario ha escrito tiene la forma – el patrón – de un correo electrónico o no.

¿Para qué?

Para decirle: “Eh tú!, eso que has escrito no es un correo electrónico, inténtalo de nuevo!”.

Ejemplo de una expresión regular

Suponemos que cinco usuarios han escrito esto:

Yo sé muy bien que ahí hay tres correos electrónicos incorrectos.

Porque mi cabeza tiene claro que un correo electrónico sigue el patrón de “loquesea@dominio.terminacion”

Pero si eso tengo que hacerlo sistemáticamente con PHP, ¿cómo lo hago?

Guay, pues ahí es donde intervienen las expresiones regulares.

En el caso de un correo electrónico, la expresión regular podría ser:

cualquier-cosa + @ (arroba) + cualquier-cosa + . (punto) + cualquier-cosa

Pero no estaría correcto.

Porque ese “cualquier-cosa” puede ser, efectivamente, cualquier cosa.

Por ejemplo:

salst=?aasgrt@=asasr.^^^^

Y eso no es un correo electrónico, ¿verdad?

Verdad.

Pues entonces, tenemos que pulir un poco la expresión.

Esta sería una expresión regular un tanto más precisa:

letras-numeros@letras-numeros.letras

Con esta expresión, en nuestra lista anterior, quedarían descartados los tres correos basura.

Quedarían descartados, quiere decir que no satisfacen/cumplen/verifican la expresión.

Sí, cool.

Pero esto no va a quedar ahí tan facilón.

Tienes que saber expresarte con el mismo arte, pero en modo PHP.

Vamos a ver cómo sería la cosa.

Expresión regular en PHP

[a-z0-9]@[a-z0-9].[a-z]

Esto viene siendo lo que viene siendo.

Las letras de la a a la zeta (a-z) y los dígitos del cero al nueve (0-9), convenientemente posicionados entre un arroba y un punto.

¿Tan fácil, de verdad?

No.

Vamos a ver el ejemplo ahora de verdad, en PHP. Yeah.

preg_match("/[a-z0-9]+@[a-z0-9]+\.[a-z]+/", $cadena_texto, $matriz_salida);

Ahhhh!! Qué susto!

No.

Primero:

Función preg_match() PHP

La función preg_match() lo que hace es comparar una expresión regular sobre una cadena de texto.

Esta función acepta cinco parámetros, pero nosotros la estamos usando con tres, porque los dos últimos de momento no nos interesan.

Parámetro 1: Patrón de expresión regular

Este es el patrón (la expresión regular) que vamos a comparar.

Parámetro 2: Cadena de texto

Esta es la cadena de texto sobre la cual vamos a comparar la expresión regular

Parámetro 3: Matriz de salida

Este es el nombre que va a tener la matriz de salida.

La función devuelve una matriz (ver qué es una matriz).

Ahora mismo seguramente no tengas ni idea de por qué, y de qué estructura tienen estos valores devueltos.

Para eso estamos aquí, para aprender.

De momento, tienes que saber que este parámetro indica el nombre de la matriz de los resultados. Nada más.

En nuestro caso, vamos a ejecutar la función sobre un caso real:

//Tenemos el correo electrónico en una variable
$correo_electronico='unaprueba@decorreo.es';

//Comprobamos si cumple el patrón
if( preg_match("/[a-z0-9]+@[a-z0-9]+\.[a-z]+/", $correo_electronico, $salida) ){
echo 'Sí cumple el patrón';
}else{
echo 'No lo cumple.';
}

Entender la expresión regular es muy fácil:

[a-z0-9]+@[a-z0-9]+\.[a-z]+

Dentro de la función, la expresión está delimitada a ambos extremos por una barra [/].

¿Cuáles son los elementos que puedo usar en un patrón?

Aquí tienes una chuleta:

Hay más cositas, pero de momento eso es lo más fácil y también lo más usado.

Grupos de captura en expresiones regulares

Vale, de momento bien.

Hemos usado una expresión regular para ver si el patrón es correcto (coincide con la cadena de texto) o no.

Pero, ¿qué pasa si yo quiero además forzar que el dominio del correo sea salamarkesa.com?

Tendría que verificar el patrón y además quedarme con una sub-parte del mismo, ¿verdad?.

Para compararlo por separado, ¿verdad?.

Piénsalo antes de seguir leyendo.

Verdad.

Vale.

En este caso, vamos a hacer una cosa: usar los grupos de captura de las expresiones regulares.

¿Y eso qué es?

Un grupo de captura es un artilugio que nos permite capturar una subsección de la expresión regular.

En nuestro caso, vamos a comprobar que el patrón se cumple, pero además vamos a obtener una matriz con dos valores (dos grupos capturados): “El nombre de usuario” y el “dominio del correo electrónico”.

//Tenemos el correo electrónico en una variable
$correo_electronico='unaprueba@salamarkesa.com';

//Comprobamos si cumple el patrón y capturamos usuario y dominio
if( preg_match("/([a-z]+)@([a-z]+\.[a-z]+)/", $correo_electronico, $salida) ){
echo 'Sí cumple el patrón';
   if($salida[2]=='salamarkesa.com'){
   echo '... Y el dominio pertenece a salamarkesa.com';
   }else{
   echo '... Pero no es un correo de salamarkesa.com';
   }
}else{
echo 'No lo cumple.';
}

Se observa en este caso que la expresión regular tiene dos paréntesis extra, exactamente en las partes del correo que queríamos capturar.

Pues es así de fácil.

Los grupos de captura van entre paréntesis.

¿Para qué quiero los grupos de captura?

Para capturar cosas.

Capturar en el sentido de atrapar.

Mira, te hago otro ejemplo.

//Tenemos una super ensalada
$ensalada='Tenemos aquí un pepino encerrado en la ensalada';

//Atrapamos el asunto
if( preg_match("/.*(pepino)/", $ensalada, $salida) ){
echo 'Sí cumple el patrón';
   echo $salida[0]; //Coincidencia completa: Tenemos aquí un pepino
   echo $salida[1]; //Coincidencia primer grupo: pepino
}

Explicación de la expresión

/.*(pepino)/

Aquí vemos la utilidad de la matriz que devuelve la función.

Esta matriz, cuando la función se ejecuta con éxito, contiene los siguientes elementos:

Otras funciones útiles

El mundo de las expresiones regulares es muy amplio.

Cada caso es una historia, pero PHP nos ofrece varias funciones de manejo de expresiones regulares, con las que se puede lograr casi cualquier cosa práctica.

A continuación te presento algunas de las más usadas.

Reemplazar patrones con preg_replace

A veces surge la necesidad de reemplazar elementos dentro de una cadena de texto. Por ejemplo, eliminar todos los espacios en blanco, sustituir un código BBCODE por un código HTML, etc…

Y más otro día.

Hehe.