En este capítulo hablaremos sobre las expresiones regulares pero orientado a PHP.
Qué son las expresiones regulares
A menudo vamos a solicitar información al usuario que se encuentra interactuando con nuestra aplicación, por ejm, vamos a querer solicitar el nombre, apellido... Cuando solicitamos información general no va a haber ninguna dificultad ya que si queremos almacenar esa información la almacenamos tal y como el usuario nos la envía. El problema viene cuando pedimos información como email, donde el usuario puede escribir cualquier cosa. En estos casos es importante validar la información que el usuario nos envía. Lo mismo ocurre si le pedimos al usuario su página web o de Facebook, nos puede enviar cualquier información que no sea una URL.
Hay otras ocasiones en las que queramos extraer una determinada porción del texto que nos están proporcionando. A partir de expresiones regulares vamos a poder extraer dicha porción de texto que el usuario haya introducido.
Cómo se define una expresión regular
Una expresión regular viene a ser una cadena que podemos almacenar en una variable. Lo primero, para definir una expresión, toda expresión debe estar delimitada por caracteres alfanuméricos.
La función que vamos a utilizar para el uso de expresiones regulares es preg_match(expresión_regular, cadena); de la siguiente forma.
Ejm
<?php
$cadena = "Hola mundo, como estás";
// Expresión que queremos verificar si existe en la cadena de arriba
$expresion = "/mundo/";
// Método que permite verificar si la expresión está en la cadena
// Este método devolverá un valor booleano
if(preg_match($expresion, $cadena)){
echo "La cadena cumple la condición";
} else {
echo "La cadena NO cumple la condición";
}
Como podemos ver en el ejm de arriba, la expresión se coloca entre dos barras (/expresión/).
Encontrar texto al inicio de la cadena
Si queremos especificar que lo que queremos encontrar se encuentra a la izquierda, para ello utilizamos el carácter (^).
Ejm
<?php
$cadena = "Paseo Avda. España 5";
// Expresión que queremos verificar si existe en la cadena de arriba
$expresion = "/^Avda/";
// Método que permite verificar si la expresión está en la cadena
// Este método devolverá un valor booleano
if(preg_match($expresion, $cadena)){
echo "La cadena cumple la condición";
} else {
echo "La cadena NO cumple la condición"; // Imprimirá el else
}
Imprimirá en pantalla el else, ya que Avda no se encuentra al inicio de la cadena.
Expresiones regulares son case sensitive
Las expresiones regulares son sensibles a mayúsculas y minúsculas, por lo que para que dejen de ser sensibles hay que agregarles lo que se denomina modificador, que en este caso es la palabra (i) el cual se escribe al final del segundo (/), de la siguiente manera.
Ejm
<?php
$cadena = "Avda. España 5";
// Expresión que queremos verificar si existe en la cadena de arriba, incluimos el modificador i
$expresion = "/^avda/i";
// Método que permite verificar si la expresión está en la cadena
// Este método devolverá un valor booleano
if(preg_match($expresion, $cadena)){
echo "La cadena cumple la condición";
} else {
echo "La cadena NO cumple la condición"; // Imprimirá el else
}
Determinado patrón al final de la cadena
Para verificar que un patrón se encuentra al final de la cadena utilizamos el carácter ($) de la siguiente manera.
Ejm
<?php
$cadena = "Avda. España 123";
// Expresión que queremos verificar si existe en la cadena de arriba
$expresion = "/123$/i";
// Método que permite verificar si la expresión está en la cadena
// Este método devolverá un valor booleano
if(preg_match($expresion, $cadena)){
echo "La cadena cumple la condición";
} else {
echo "La cadena NO cumple la condición";
}
Nos devolverá un TRUE ya que '123' sí se encuentra al final de la cadena.
Meta caracteres
Tanto el símbolo de dólar ($) como el símbolo (^) se los conoce como metacaracteres, pero estos no son los únicos meta caracteres, existen algunos más.
- ^: busca el patrón al inicio de la cadena
- $: busca el patrón al final de la cadena
- []: busca cualquiera de los patrones entre los corchetes
- - (a-u): busca desde la a hasta la u
- Lista de exclusión: para ello volvemos a utilizar el símbolo ^. Este símbolo debe ir al principio.
- Carácter de escape: cuando queremos usar símbolos que funcionan como meta caracteres, y que sean sólo caracteres, hemos de usar el carácter de escape, representado por el signo (\)
- Meta caracter punto (.): el punto hace referencia a cualquier caracter de cualquier tipo (ya sean vocales, números o caracteres no alfanuméricos)
- \w: hace referencia a cualquier caracter alfanumérico (sean números o letras y el guion bajo)
- \W: hace referencia a caracteres NO alfanuméricos
- \d: hace referencia a caracteres numéricos
- \D: hace referencia a caracteres NO numéricos
- El carácter puede o no puede existir: para ello se utiliza el meta carácter asteriso (*) al final del carácter que deseamos verificar
- El carácter existe por lo menos una vez: lo que significa que puede existir al menos una o más veces. Para ello se utiliza el meta carácter más (+) al final del carácter que queremos verificar
- Existencia o NO de un determinado caracter: para ello se utiliza el meta caracter de interrogación (?) que indicará que el caracter pueda o no existir en la expresión, y cumplirá la validación esté o no dicho caracter.
- Cantidad de veces que se pueda repetir un caracter: para ello se utiliza las llaves {3}. Dentro de las llaves ponemos la cantidad de veces que se debe repetir el caracter (en este caso 3 veces). También podemos usar la expresión {2, 5} que indica que el caracter se puede encontrar entre 2 y 5 veces
- Meta caracter paréntesis (): los paréntesis en las expresiones regulares permiten crear subpatrones, como pequeños patrones dentro del patrón principal. Se puede decir que este meta caracter es el más importante en las expresiones regulares
Ejm corchetes
<?php
$cadena = "Hole";
// Expresión que queremos verificar si existe en la cadena de arriba
$expresion = "/hol[aeiou]/i";
// Método que permite verificar si la expresión está en la cadena
// Este método devolverá un valor booleano
if(preg_match($expresion, $cadena)){
echo "La cadena cumple la condición";
} else {
echo "La cadena NO cumple la condición";
}
Ejm corchetes y guión medio
<?php
$cadena = "Hole";
// Expresión que queremos verificar si existe en la cadena de arriba
$expresion = "/hol[a-u]/i";
// Método que permite verificar si la expresión está en la cadena
// Este método devolverá un valor booleano
if(preg_match($expresion, $cadena)){
echo "La cadena cumple la condición";
} else {
echo "La cadena NO cumple la condición";
}
Ejm corchetes y guión medio (2)
<?php
$cadena = "Hol5";
// Expresión que queremos verificar si existe en la cadena de arriba
$expresion = "/hol[a-u0-9]/i";
// Método que permite verificar si la expresión está en la cadena
// Este método devolverá un valor booleano
if(preg_match($expresion, $cadena)){
echo "La cadena cumple la condición";
} else {
echo "La cadena NO cumple la condición";
}
Ejm lista de exclusión
<?php
$cadena = "Hola";
// Expresión que queremos verificar si existe en la cadena de arriba
$expresion = "/hol[^a-u]/i";
// Método que permite verificar si la expresión está en la cadena
// Este método devolverá un valor booleano
if(preg_match($expresion, $cadena)){
echo "La cadena cumple la condición";
} else {
echo "La cadena NO cumple la condición"; // Imprimirá esto
}
Ejm carácter de escape
<?php
$cadena = "Hol]";
// Expresión que queremos verificar si existe en la cadena de arriba
$expresion = "/hol[a-u\]]/i";
// Método que permite verificar si la expresión está en la cadena
// Este método devolverá un valor booleano
if(preg_match($expresion, $cadena)){
echo "La cadena cumple la condición";
} else {
echo "La cadena NO cumple la condición";
}
Ejm uso del meta carácter asterisco (*)
<?php
$cadena = "Holaaaaaaa";
// Expresión que queremos verificar si existe en la cadena de arriba
// El carácter a se está verificando varias veces
$expresion = "/hola*/i";
// Método que permite verificar si la expresión está en la cadena
// Este método devolverá un valor booleano
if(preg_match($expresion, $cadena)){
echo "La cadena cumple la condición";
} else {
echo "La cadena NO cumple la condición";
}
En el caso del asterisco, puede o no puede existir, por lo tanto si no encuentra el carácter a, imprimiría un TRUE.
Ejm uso del meta carácter más (+)
<?php
$cadena = "Hol";
// Expresión que queremos verificar si existe en la cadena de arriba
$expresion = "/hola+/i";
// Método que permite verificar si la expresión está en la cadena
// Este método devolverá un valor booleano
if(preg_match($expresion, $cadena)){
echo "La cadena cumple la condición";
} else {
echo "La cadena NO cumple la condición";
}
En este caso la cadena NO cumplirá la condición
Ejm uso del meta caracter de interrogación (?)
<?php
$cadena = "Hol";
// Expresión que queremos verificar si existe en la cadena de arriba
$expresion = "/ho?la/i";
// Método que permite verificar si la expresión está en la cadena
// Este método devolverá un valor booleano
if(preg_match($expresion, $cadena)){
echo "La cadena cumple la condición"; // IMPRIMIRÁ TRUE
} else {
echo "La cadena NO cumple la condición";
}
Ejm uso de llaves
<?php
$cadena = "Holaaa";
// Expresión que queremos verificar si existe en la cadena de arriba
$expresion = "/hola{3}/i";
// Método que permite verificar si la expresión está en la cadena
// Este método devolverá un valor booleano
if(preg_match($expresion, $cadena)){
echo "La cadena cumple la condición"; // IMPRIMIRÁ TRUE
} else {
echo "La cadena NO cumple la condición";
}
Ejm uso de paréntesis y barra perpendicular (|)
<?php
$cadena = "Llegaré pronto que voy volando";
// Expresión que queremos verificar si existe en la cadena de arriba
$expresion = "/Llegaré pronto que voy (vol|and)ando/i";
// Método que permite verificar si la expresión está en la cadena
// Este método devolverá un valor booleano
if(preg_match($expresion, $cadena)){
echo "La cadena cumple la condición"; // IMPRIMIRÁ TRUE
} else {
echo "La cadena NO cumple la condición";
}
Capturar subpatrones
Los subpatrones que tenemos podemos capturarlos. Si observamos el último ejercicio, queremos saber si se ha utilizado el valor vol o el valor and del subpatrón creado. Dentro del método preg_match() pasamos un tercer parámetro llamado $matches, este va a crear un Array, dentro de dicho Array van a quedar capturados los valores de dicho subpatrón, en nuestro caso el valor que va a quedar capturado dentro del Array es vol.
Veamos el ejm de arriba con la nueva sintaxis.
Ejm
<?php
$cadena = "Llegaré pronto que voy volando";
// Expresión que queremos verificar si existe en la cadena de arriba
$expresion = "/Llegaré pronto que voy (vol|and)ando/i";
// Método que permite verificar si la expresión está en la cadena
// Este método devolverá un valor booleano
if(preg_match($expresion, $cadena, $matches)){
echo "La cadena cumple la condición"; // IMPRIMIRÁ TRUE
} else {
echo "La cadena NO cumple la condición";
}
var_dump($matches);
Gracias a estos subpatrones nosotros podremos hacer capturas de los id de la web de Youtube por ejm.
Ejm práctico
Vamos a crear un ejm práctico en el que vamos a determinar, como dijimos antes, el id de un video de Youtube.
Ejm
<?php
// Recuperar un video mediante un id de Youtube
$url = "https://youtu.be/UEFY1IT0Zfg?si=gBsiPjaJ15oOJ8ZF";
// Otro tipo de URL en Youtube
// $url = "https://www.youtube.com/watch?v=UEFY1IT0Zfg";
$patron = "%^(?:https://)?(?:www\.)?(?:youtu\.be/|youtube\.com/watch\?v=)(\w{10,12})%i";
if(preg_match($patron, $url, $matches)){
echo "La URL es válida";
echo "<br />";
var_dump($matches);
} else {
echo "La URL no es válida";
}
// Vamos a rescatar el id, para ello creamos el subpatrón que rescate el id de Youtube
// Si no nos interesa recuperar la información de algún subpatrón, podemos anteponer ?: en el subpatrón
// que no queramos recuperar
a