15, octubre - 2018

Expresiones regulares en PHP

Expresiones regulares en PHP

¿Qué son las expresiones regulares de la programación?

Las expresiones regulares en PHP y prácticamente en cualquier lenguaje de programación, son formas minimizadas y compactas, de describir patrones de textos para realizar búsquedas y comprobaciones.
Se trata de utilizar caracteres especiales para indicar distintos metasignificados.

Por ejemplo, una expresión regular en PHP podría ser la siguiente:

[a-zA-Z]

Significaría que buscamos cualquier carácter que estuviera comprendido entre los rangos de letras entre la a y la z, en formato de mayúsculas o de minúsculas.
De esta forma, una expresión regular será. La manera en la que le indicamos a la máquina qué es lo que queremos encontrar exactamente dentro de un determinado texto. Siendo muy útiles para crear distintas fórmulas que nos van a facilitar mucho este tipo de consultas.

Conjuntos de caracteres y clases de caracteres

Dentro de las expresiones regulares podemos utilizar conjuntos y clases de caracteres específicos para aumentar el potencial y los rangos de búsquedas que deseamos. Vienen a ser una especie de comodines, que bien utilizados, pueden hacer que la expresión sea realmente compleja.

Por ejemplo, podemos utilizar el carácter ‘.’ como comodín de la siguiente forma

.mail

De esta forma, nos estaríamos refiriendo la cualquier palabra terminada en mail, como email, mymail, yourmail, etc… Sería un tipo de comodín, de coincidencia.
De la misma manera, podemos limitar los tipos de coincidencias, por ejemplo a numéricas, alfabéticas, o a cualquier otra combinación que necesitemos. Siguiendo con el ejemplo anterior, de la forma que está declarado, coincidiría también con la cadena 2mail, si no queremos que los números entren en la declaración podríamos declarar ésta de la siguiente manera

[a-zA-Z]mail

Ahora la cadena solo coincidiría con los rangos del abecedario de la a la z, tanto en mayúsculas como en minúsculas, y ahora sí, la cadena 2mail la declararía como false, al contener un número en la parte izquierda de la misma.

Todo aquello que encerremos entre los corchetes [], se consideran clases de caracteres (conjuntos de valores en rangos que podemos implementar). Con el guión medio le estamos especificando un rango. Los rangos pueden ser por ejemplo los descritos a-z, o 0-5 (los números del cero al cinco). O si en lugar de un rango queremos especificar nosotros qué caracteres son los que van a coincidir, en lugar de poner el guión medio, pondríamos la lista de caracteres directamente.

[aeiou]mail

En este caso. Coincidirían los caracteres de vocales, de tal forma que, email, amail o umail sí concidirían, pero rmail o tmail no.

Otro de los comodines útiles es el de exclusión, representado por el signo ^, cuando lo ponemos en un rango lo que estamos indicando es que no coincida.
Volviendo al ejemplo inverso si ponemos

[^a-z]mail

Estamos indicando que no puede contener ninguna letra del abecedario en minúscula antes de la cadena mail , así que, 1mail sí coincidiría, pero 5mail no.
El símbolo de acento circunflejo ^ dentro de los corchetes, equivale a decir ‘no’.

Además de todo esto, podemos también usar fórmulas en las expresiones regulares ya predefinidas, también muy útiles para invocar la expresión adaptándola a nuestras necesidades.

Podemos ver la…

Lista de fórmulas predefinidas en las expresiones regulares

Subexpresiones regulares

También nos puede resultar útil, utilizar más de una expresión o hacer que las coincidencias sen más amplias. Por ejemplo, podemos utilizar los paréntesis y el signo comodín *, igual que haríamos en una expresión aritmétrica, o de programación. Vemos un sencillo ejemplo

(miguel-ruben)+@mail.com

Estaríamos indicando que buscamos cualquier cadena que contenga miguel o ruben, seguido de cualquier carácter y terminado en mail, así, miguel@mail.com coincidiría, y ruben@mail.com también, pero el resto de cadenas no.

Repeticiones en las expresiones regulares

Podemos también necesitar indicarle al script. Que puede haber una repetición de alguna de las cadenas a buscar dentro de la expresión. Para ello, tenemos dos formas de indicar los comodines necesarios. Con el signo * (cero o más veces) y con el signo + (una o más veces). Este último ya lo hemos visto en el ejemplo anterior, indicando que la parte de la cadena @mail.com, debe aparecer por lo menos una vez. Podemos ver un ejemplo del primero, del signo asterisco.

[[:upper:]]+@mail.com

Indicaría que al menos tiene que haber una letra mayúscula en la parte izquierda de la expresión, siendo válidas por ejemplo las expresiones ‘Anton@mail.com’ o ‘Miguel@mail.com’ pero no por ejemplo estas otras, ‘anton@mail.com’ o ‘miguel@mail.com).

Contadores de repeticiones en expresiones regulares

En caso de necesitar que el elemento que puede repetirse, se puede repetir solo un número determinado de veces, podemos hacerlo de una forma similar a la que haríamos para expresar un array, entre llaves {}. Se puede indicar un número exacto de veces {2} en este caso dos veces, o un rango de veces por ejemplo {2,4} en este otro caso, entre dos y cuatro veces. Si dejamos en blanco el número de la derecha, por ejemplo {2,}, significaría que al menos dos veces. Igual, vemos un ejemplo.

[[:upper:]]{5}+@mail.com

Estamos indicando que tiene que haber cinco letras en mayúsculas, seguidas de la cadena @mail.com

Anclajes en las partes primeras y últimas de las cadenas

Siguiendo con los comodines y las ‘fórmulas’ para indicar expresiones regulares en las cadenas de PHP. Podemos utilizar comodines para indicar si deseamos que la expresión o coincidencia marcada se encuentre al principio o al final de la cadena, o en los dos lugares a la vez. Ésto se consigue gracias a los acentos circunflejos ^ (para búsquedas al principio de la cadena) y al signo de dollar $ (para búsquedas al final de la cadena). Podemos ver ejemplos.

^[a-z]

Buscaríamos que la cadena comenzase por un carácter alfabético.

[a-z]$

Buscaríamos que la cadena terminase con un carácter alfabético.

^[a-z]$

Buscaríamos que la cadena comenzase y terminase con un carácter alfabético.

Representación de opciones en las expresiones regulares

Podemos representar una opción, igual que lo hacemos en las expresiones condicionales, el signo | representa indicar una opción u otra. Si deseamos buscar varias cadenas diferentes en la expresión. Lo haríamos de la siguiente manera.

uno|dos|tres

Buscaríamos que la expresión contuviera las cadenas uno, dos o tres.

Cómo escapar caracteres especiales en las expresiones regulares

De igual forma. Si deseamos escapar caracteres especiales tales como, . ; $ etc… Debemos hacerlo con la barra invertida, exáctamente igual que haríamos en un string, en caso de necesitar escapar la propia barra invertida, lo haríamos colocando una segunda barra primero //. Otro aspecto destacable de los caracteres especiales es el uso de comillas, es mucho mejor usar la comilla simple en una expresión regular antes que las dobles. Usando las simples nos ahorraremos después muchos problemas.

Listado completo de caracteres especiales para expresiones regulares

Es importante destacar. Que en los caracteres especiales, va a variar su significado dependiendo de si éstos se encuentran dentro o fuera de los corchetes [ ], siendo mucho más amplia la lista de caracteres especiales para expresiones regulares, en los primeros (fuera de corchetes) que en los segundos.
Vamos a ver los listados completos de caracteres especiales que podemos utilizar en las expresiones regulares de PHP.

Si se encuentran fuera de los corchetes

Si se encuentran dentro de los corchetes

Casos prácticos del uso de expresiones regulares en PHP

Búsqueda de patrones con expresiones regulares y la función preg_match()

Vamos a ver ahora los casos prácticos (lo que más nos interesa) en los que podemos utilizar las expresiones regulares y caracteres especiales del sistema.
Puede el caso práctico más utilizado sea el de validar una cadena como correo electrónico válido. Éste ha de estar compuesto por una serie de caracteres de obligado cumplimiento, como puede ser el caso de la @ (sin ella no podría ser una dirección de correo electrónico), el del punto y el de la terminación lógica del dominio. Incluso podríamos restringir dicha terminación a tipos de dominios específicos como .com, .es, .org, etc…

Para poder determinar este ejemplo necesitaríamos utilizar una expresión regular similar a esta

^[a-zA-Z0-9_\-.]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-.]^

Describimos paso por paso la expresión. El comienzo ^[a-zA-Z0-9_\-.]+@ está indicando, la revisión al principio (^) de la cadena, que ésta comience por un carácter alfanumérico, o, un guión bajo, o, un guión medio (escapado con la barra invertida \-) o, un punto (vemos que el punto va justo al final de la expresión, de esa forma pierde su significado especial de comodín). Seguido de la arroba (+@). Después, ha de continuar por un carácter alfanumérico, o, un guión medio (también escapado por la barra invertida), seguido de un punto +\. (escapado con barra invertida), seguido de [a-zA-Z0-9\-.]^ la terminación TDL del dominio, que podrá estar compuesta por caracteres alfanuméricos, incluyendo guiones medios y puntos (para el caso de los subdominios).

Llevando la función a la práctica podríamos utilizar las funciones ereg() y eregi(), para la búsqueda de cadenas con expresiones regulares en versiones de PHP hasta la 5.3. La primera es exactamente igual a la segunda con la excepción que discrimina entre mayúsculas y minúsculas, eregi() no discrimina.

En versiones posteriores a 5.03 o en la que estamos actualmente 7.01, debemos usar la función preg_match, la cual admite dos parámetros obligatorios (la cadena donde deseamos buscar y el patrón de búsqueda) y dos opcionales. Veamos los parámetros obligatorios para que nos aplique una búsqueda a una cadena de texto. Terminaríamos de aplicar la expresión regular de la siguiente manera.

$email = "direccion@mail.com";
if(preg_match('^[a-zA-Z0-9_\-.]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-.]^', $email))
echo "Dirección de email válida";
else
echo "Dirección de email NO válida";
/** RESPUESTA */
// Dirección de email válida

También podemos ilustrar estos otros dos ejemplos

$cadena = "ofertas@mail.com";
preg_match("(tienda|comprar|ofertas)", $cadena, $respuesta);
print_r($respuesta);
/** RESPUESTA */
// Array ( [0] => ofertas )

Esta función sería muy práctica para buscar si un determinado email va dirigido a un departamento en concreto, como vemos, si el email contiene algunas de las claves tienda, comprar u ofertas, nos devolverá un true y un array con el resultado de la coincidencia que haya encontrado. Justo lo que buscábamos.

Sustitución de subcadenas con expresiones regulares y la función preg_replace()

También se pueden usar las expresiones regulares en PHP para sustituir partes de una cadena. Similar a cuando usarmos str_replace(). Esta función buscará un patrón asignado en una cadena y, en caso de encontrarlo lo sustituirá por otro que le hayamos también asignado. El patrón de búsqueda y los de reemplazo podrán ser tanto strings normales como arrays de strings. Vemos un ejemplo de su uso.

$cadena = 'Pedro como pipas en el puesto.';
$patrones = array();
$patrones[0] = '/Pedro/';
$patrones[1] = '/pipas/';
$patrones[2] = '/puesto/';
$sustituciones = array();
$sustituciones[2] = 'Rafa';
$sustituciones[1] = 'castañas';
$sustituciones[0] = 'parque';
echo preg_replace($patrones, $sustituciones, $cadena);
/** RESPUESTA */
/** Rafa como castañas en el parque. */
//////////////////////////////////////////////////////
$cadena2 = "Ayer vi una película muy interesante.";
$patron2 = "/interesante/";
$sustitucion2 = "aburrida";
echo preg_replace($patron2, $sustitucion2, $cadena2);
/** RESPUESTA */
/** Ayer vi una película muy aburrida. */
//////////////////////////////////////////////////////

Nota: Se puede apreciar que, en los patrones de búsqueda colocamos las dos barras invertidas como signo de escape, una al principio y otra al final de la cadena. Esto aunque no es del todo necesario es aconsejable para evitar posibles errores de sintaxis.

Dividir strings mediante expresiones regulares con la función preg_split()

Otra de las utilidades que pueden tener las expresiones regulares de PHP es la dividir cadenas de texto mediante patrones delimitados. La función preg_split(), nos devolverá un array de elementos (rodajas), dependiendo de la expresión que hayamos marcado como búsqueda. Podemos ver un ejemplo de su uso a continuación.

// Creamos una función que busque alguno de los siguientes supuestos
// Cualquier salto de línea, tabulación o espacio
// Si encuenta alguno de los signos . ; , : -
$str = preg_split("/[\s,.;:^-]+/", "uno,dos.tres:cuatro;cinco-seis");
print_r($str);
/** RESPUESTA */
/** Array ( [0] => uno [1] => dos [2] => tres [3] => cuatro [4] => cinco [5] => seis ) */
//////////////////////////////////////////////////////

Algunas expresiones regulares útiles que nos pueden servir y ayudar

Vamos a terminar esta lección listando algunas expresiones regulares ya diseñadas, listas para su uso por parte de los desarrolladores de código fuente. Tener en cuenta que puede que las tengáis que retocar un poco dado que es muy difícil crear a la primera una expresión que pueda cubrir todos los supuestos para los que fue diseñada. No obstante siguen siendo útiles y funcionales. Son éstas.

// Valida dirección URL
$valida_direccionURL = 'http://unaweb';
$URL = preg_match('/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \?=.-]*)*\/?$/', $valida_direccionURL) ? "Válido" : "NO Válido";
echo $URL;
/**  RESPUESTA */
/** NO Válido */
/////////////////////////////////////////////////////////////
// Valida dirección de email
$valida_email = 'direcciondemail@mail.com';
$mail = preg_match('^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})^', $valida_email) ? "Válido" : "NO Válido";
echo $mail;
/**  RESPUESTA */
/** Válido */
/////////////////////////////////////////////////////////////
// Valida un número de teléfono (a nivel nacional)
$valida_telefono = '34 911112211';
$telef = preg_match('^(\+34|0034|34)?[6|7|9][0-9]{8}^', $valida_telefono) ? "Válido" : "NO Válido";
echo $telef;
/**  RESPUESTA */
/** Válido */
/////////////////////////////////////////////////////////////
// Valida una fecha en formato (DD/MM/AAAA)
$valida_fecha = '01/01/2018';
$fecha = preg_match('^([0-2][0-9]|3[0-1])(\/|-)(0[1-9]|1[0-2])\2(\d{4})^', $valida_fecha) ? "Válido" : "NO Válido";
echo $fecha;
/**  RESPUESTA */
/** Válido */
¿Te ha parecido interesante este contenido..?
En ese caso, te pedimos por favor que nos des tu valoración graicas a esto podemos mejorar nuestras lecciones. Gracias.
1 estrella2 estrellas3 estrellas4 estrellas5 estrellas (1 votos, promedio: 5,00 de 5)
Cargando…

Social Media

  • YouTube

    Suscríbete a nuestro canal de YouTube para ver todos nuestros vídeos sobre programación

  • Twitter

    Síguenos en Twitter e infórmanos de ello, es muy probable que también te sigamos

  • Facebook

    Estamos pensando si abrir una página de Facebook o no...

  • LinkedIn

    En breve...

  • Instagram

    En breve...

  • Github

    En breve...

A %d blogueros les gusta esto: