Las expresiones regulares son usadas para realizar búsquedas avanzadas y reemplazar texto en una cadena de caracteres utilizando un patrón de caracteres.
Lo primero que debes saber es que en el lenguaje PHP existen dos tipos de funciones de expresiones regulares y que ambas usan una síntaxis algo diferente: las funciones POSIX (que han quedado obsoletas< desde la versión de PHP 5.3.0, por lo que no se recomienda su uso) y las funciones PCRE (Perl Compatible Regex library) compatibles con el lenguaje Perl.
Algunos de los caracteres especiales usados para crear patrones de caracteres en expresiones regulares son:
- ^: principio de la cadena.
- $: final de la cadena.
- .: se admite cualquier carácter que no sea un salto de línea.
- x|y: la coincidencia es positiva si se encuentra alguno de los caracteres especificados.
- (abcde): la coincidencia es positiva si se encuentra el texto indicado entre los paréntesis.
Podemos usar corchetes para definir ciertas condiciones de búsqueda en el patrón de caracteres:
- [abc]: se admite cualquier carácter que esté entre los indicados.
- [^abc]: Cuando se usa '^' al principio de los corchetes indica negación: se admite cualquier caracter que no esté entre los indicados.
- [0-9]: se admiten sólo dígitos.
- [A-Z]: se admiten sólo letras en mayúsculas.
- [a-z]: se admiten sólo letras en minúsculas.
- [A-z] o [a-zA-Z]: se admiten sólo letras en mayúsculas o minúsculas.
Para especificar repetición dentro de una cadena usaremos:
- *: el carácter se encuentra o no, pudiéndose repetir un número indeterminado de veces.
- +: el carácter debe existir, pudiéndose repetir un número indeterminado de veces.
- ?: el carácter puede o no existir, una sola vez.
- {n}: el carácter se repite el número de veces especificado entre las llaves.
- {n,m}: el carácter se debe repetir un número de veces, entre el mínimo y máximo indicados.
También podemos usar los siguientes metacaracteres para configurar la búsqueda y tomar control sobre caracteres no imprimibles que puedan existir:
- \d: admite dígito.
- \D: admite cualquier carácter alfabético, no numérico.
- \f: se encuentra un salto de página.
- \n: se encuentra un salto de línea.
- \s: se admiten referentes a espacios, como un espacio en blanco o tabulador.
Finalmente disponemos de los siguientes modificadores:
- i: especifica que la búsqueda se realizará sin diferenciar entre mayúsculas y minúsculas (funciona con expresiones regulares de tipo PCRE, para POSIX usar las funciones que no hagan dicha distinción).
Ejemplos de patrones en PCRE:
$patron01 = "/gratis/i"; // Busca 'gratis' (en mayúsculas o minúsculas)
$patron02 = "/^[a-zA-Z\s]*$/"; // La cadena sólo puede contener letras y espacios
$patron03 = "/^\d{2}\/\d{2}\/\d{4}$/"; // La cadena es una fecha válida
Ejemplos equivalentes en POSIX:
$patron01 = "gratis"; // Busca 'gratis' (en mayúsculas o minúsculas)
$patron02 = "^[a-zA-Z\s]*$"; // La cadena sólo puede contener letras y espacios
$patron03 = "^\d{2}\/\d{2}\/\d{4}$"; // La cadena es una fecha válida
Fíjate en que los patrones en PCRE se usa como delimitador una barra a principio y a final, mientras que los patrones en POSIX no.
Observa también en el primer patrón en POSIX omitimos el modificador /i puesto que no es reconocido por las funciones de tipo POSIX (deberemos usar las funciones que incorporen la capacidad de no distinguir entre mayúsculas y minúsculas).
En los siguientes apartados veremos algunas funciones útiles de cada uno de estos dos tipos de expresiones regulares.

Recuerda que las expresiones regulares de tipo POSIX han quedado obsoletas desde la versión de PHP 5.3.0 !!

Si compruebas que no te funcionan bien las expresiones regulares asegúrate de guardar el archivo con codifición UTF-8

Vea también: [ Expresiones POSIX ] - [ Expresiones PCRE ] - [ Delimitadores ] - [ Modificadores ]

Vea también: [ Diferencias entre POSIX y PCRE ]
Usaremos la función preg_match() para comprobar si la cadena especificada en el patrón de búsqueda existe dentro de la cadena de texto principal: devolverá cero si no se ha cumplido lo especificado en el patrón de caracteres, 1 en caso de que sí exista dentro de la principal, o bien false si ocurrió algún error.
preg_match() no realizará una búsqueda global ni aunque se indique modificador alguno. Para realizar una búsqueda global deberemos usar la función preg_match_all(), que veremos un poco más adelante.
<?php
// Cadenas de caracteres:
$cadena01 = "Cursos de informática gratis";
$cadena02 = "Cu3rsos de informática gratis";
$cadena03 = "CURSOS de informática gratis";
$cadena04 = "CURSOSdeinformáticagratis";
$cadena05 = "123456789012345";
// Patrones:
$patron01 = "/^[a-zA-Z\s]+$/"; // La cadena contiene contiene sólo caracteres (no dígitos) y espacios
$patron02 = "/[a-zA-Z\s]/"; // La cadena contiene contiene ALGÚN caracter alfabético o espacio
echo "CADENA: [".$cadena01."]<br />";
echo "¿Contiene sólo caracteres (no dígitos) y espacios?: ".preg_match($patron01, $cadena01)."<br />";
echo "¿Contiene ALGÚN caracter alfabético o espacio?: " .preg_match($patron02, $cadena01)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena02."]<br />";
echo "¿Contiene sólo caracteres (no dígitos) y espacios?: ".preg_match($patron01, $cadena02)."<br />";
echo "¿Contiene ALGÚN caracter alfabético o espacio?: " .preg_match($patron02, $cadena02)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena03."]<br />";
echo "¿Contiene sólo caracteres (no dígitos) y espacios?: ".preg_match($patron01, $cadena03)."<br />";
echo "¿Contiene ALGÚN caracter alfabético o espacio?: " .preg_match($patron02, $cadena03)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena04."]<br />";
echo "¿Contiene sólo caracteres (no dígitos) y espacios?: ".preg_match($patron01, $cadena04)."<br />";
echo "¿Contiene ALGÚN caracter alfabético o espacio?: " .preg_match($patron02, $cadena04)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena05."]<br />";
echo "¿Contiene sólo caracteres (no dígitos) y espacios?: ".preg_match($patron01, $cadena05)."<br />";
echo "¿Contiene ALGÚN caracter alfabético o espacio?: " .preg_match($patron02, $cadena05)."<br />";
?>
Observa que en el segundo patrón de caracteres del ejemplo hemos usado /i para que no se distinga entre mayúsculas y minúsculas.
En el tercer patrón de caracteres usamos los símbolos ^ y $ para indicar el principio y final de la cadena respectívamente: con ello estamos indicando que queremos encontrar en dicha cadena una coincidencia exacta de lo especificado en el patrón de caracteres... no si los caracteres se encuentran en cualquier parte de la misma.

Si compruebas que no te funcionan bien las expresiones regulares asegúrate de guardar el archivo con codifición UTF-8.

Vea también: [ preg_match() ] - [ Buscar texto en una cadena sin usar expresiones regulares ]
Las funciones de tipo POSIX equivalentes a las explicadas en el punto anterior son ereg() (diferencia entre mayúsculas y minúsculas) y eregi() (no distingue entre mayúsculas y minúsculas), las cuales devuelven false en caso de encontrarse coincidencias u ocurrir un error:
<?php
// Cadenas de caracteres:
$cadena01 = "patron";
$cadena02 = "de patrones";
$cadena03 = "PATRONes";
// Patrones:
$patron01 = "patron"; // La cadena contiene 'patron', en minúsculas
$patron02 = "patron"; // La cadena contiene 'patron', en minúsculas
$patron03 = "^patron$"; // La cadena es exáctamente 'patron', en minúscula
// Resultado:
echo "CADENA: [".$cadena01."]<br />";
echo "¿La cadena contiene 'patron' en minúscula?: ".ereg($patron01, $cadena01)."<br />";
echo "¿La cadena contiene 'patron' en mayúsculas o minúsculas?: ".eregi($patron02, $cadena01)."<br />";
echo "¿La cadena es exáctamente 'patron', en minúsculas?: ".ereg($patron03, $cadena01)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena02."]<br />";
echo "¿La cadena contiene 'patron' en minúscula?: ".ereg($patron01, $cadena02)."<br />";
echo "¿La cadena contiene 'patron' en mayúsculas o minúsculas?: ".eregi($patron02, $cadena02)."<br />";
echo "¿La cadena es exáctamente 'patron', en minúsculas?: ".ereg($patron03, $cadena02)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena03."]<br />";
echo "¿La cadena contiene 'patron' en minúscula?: ".ereg($patron01, $cadena03)."<br />";
echo "¿La cadena contiene 'patron' en mayúsculas o minúsculas?: ".eregi($patron02, $cadena03)."<br />";
echo "¿La cadena es exáctamente 'patron', en minúsculas?: ".ereg($patron03, $cadena03)."<br />";
?>
El resultado será el mismo que en el ejemplo anterior, salvo que en éste no se mostrarán los valores cero ya que en su lugar se obtiene false.

Recuerda que las expresiones regulares de tipo POSIX han quedado obsoletas desde la versión de PHP 5.3.0 !!

Si compruebas que no te funcionan bien las expresiones regulares asegúrate de guardar el archivo con codifición UTF-8.

Vea también: [ ereg() ] - [ eregi() ] - [ Buscar texto en una cadena sin usar expresiones regulares ]
Si necesitamos averiguar cuántas veces aparece una subcadena dentro de otra usaremos la función preg_match_all(), que retornará el número de veces que se ha encontrado la subcadena dentro de la principal (cero si no se ha hallado), o bien false si ocurrió algún error.
Para usarla es necesario indicar el tercer parámetro, en el cual se guardará un array multidimensional con dichas coincidencias.
<?php
$cadena = "Aprende a usar tu ordenador en aprender-informatica.com";
$patron = "/aprende/i"; // La cadena contiene 'aprende', en mayúsculas o minúsculas
echo "CADENA: [".$cadena."]<br />";
echo "¿La cadena contiene 'aprende' en minúscula?: ".preg_match($patron, $cadena)."<br />";
echo "¿La cadena contiene 'aprende' en minúscula?: ".preg_match_all($patron, $cadena, $aCoincidencias)."<p />";
print_r( $aCoincidencias );
?>

Si compruebas que no te funcionan bien las expresiones regulares asegúrate de guardar el archivo con codifición UTF-8.

Vea también: [ preg_match_all() ]
Ejemplos PCRE (ten en cuenta que en patron01 usamos + porque deseamos que al menos haya un carácter de entre los especificados... usaríamos * si admitiéramos como válida una cadena vacía):
<?php
// Cadenas de caracteres:
$cadena01 = "Cursos de informática gratis";
$cadena02 = "Cu3rsos de informática gratis";
$cadena03 = "CURSOS de informática gratis";
$cadena04 = "CURSOSdeinformáticagratis";
$cadena05 = "123456789012345";
// Patrones:
$patron01 = "/^[a-zA-Z\s]+$/"; // La cadena contiene contiene sólo caracteres (no dígitos) y espacios
$patron02 = "/[a-zA-Z\s]/"; // La cadena contiene contiene ALGÚN caracter alfabético o espacio
echo "CADENA: [".$cadena01."]<br />";
echo "¿Contiene sólo caracteres (no dígitos) y espacios?: ".preg_match($patron01, $cadena01)."<br />";
echo "¿Contiene ALGÚN caracter alfabético o espacio?: " .preg_match($patron02, $cadena01)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena02."]<br />";
echo "¿Contiene sólo caracteres (no dígitos) y espacios?: ".preg_match($patron01, $cadena02)."<br />";
echo "¿Contiene ALGÚN caracter alfabético o espacio?: " .preg_match($patron02, $cadena02)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena03."]<br />";
echo "¿Contiene sólo caracteres (no dígitos) y espacios?: ".preg_match($patron01, $cadena03)."<br />";
echo "¿Contiene ALGÚN caracter alfabético o espacio?: " .preg_match($patron02, $cadena03)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena04."]<br />";
echo "¿Contiene sólo caracteres (no dígitos) y espacios?: ".preg_match($patron01, $cadena04)."<br />";
echo "¿Contiene ALGÚN caracter alfabético o espacio?: " .preg_match($patron02, $cadena04)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena05."]<br />";
echo "¿Contiene sólo caracteres (no dígitos) y espacios?: ".preg_match($patron01, $cadena05)."<br />";
echo "¿Contiene ALGÚN caracter alfabético o espacio?: " .preg_match($patron02, $cadena05)."<br />";
?>
Ejemplos POSIX (el resultado será el mismo que en el caso anterior, salvo que no se mostrará nada en lugar de los ceros ya que en su lugar se ha obtenido false):
<?php
// Cadenas de caracteres:
$cadena01 = "Cursos de informática gratis";
$cadena02 = "Cu3rsos de informática gratis";
$cadena03 = "CURSOS de informática gratis";
$cadena04 = "CURSOSdeinformáticagratis";
$cadena05 = "123456789012345";
// Patrones:
$patron01 = "^[a-zA-Z ]+$"; // La cadena contiene contiene sólo caracteres (no dígitos) y espacios
$patron02 = "[a-zA-Z\s]"; // La cadena contiene contiene ALGÚN caracter alfabético o espacio
echo "CADENA: [".$cadena01."]<br />";
echo "¿Contiene sólo caracteres (no dígitos) y espacios?: ".ereg($patron01, $cadena01)."<br />";
echo "¿Contiene ALGÚN caracter alfabético o espacio?: ".ereg($patron02, $cadena01)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena02."]<br />";
echo "¿Contiene sólo caracteres (no dígitos) y espacios?: ".ereg($patron01, $cadena02)."<br />";
echo "¿Contiene ALGÚN caracter alfabético o espacio?: ".ereg($patron02, $cadena02)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena03."]<br />";
echo "¿Contiene sólo caracteres (no dígitos) y espacios?: ".ereg($patron01, $cadena03)."<br />";
echo "¿Contiene ALGÚN caracter alfabético o espacio?: ".ereg($patron02, $cadena03)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena04."]<br />";
echo "¿Contiene sólo caracteres (no dígitos) y espacios?: ".ereg($patron01, $cadena04)."<br />";
echo "¿Contiene ALGÚN caracter alfabético o espacio?: ".ereg($patron02, $cadena04)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena05."]<br />";
// Las siguientes devuelven 'false' por eso no se muestra nada:
echo "¿Contiene sólo caracteres (no dígitos) y espacios?: ".ereg($patron01, $cadena05)."<br />";
echo "¿Contiene ALGÚN caracter alfabético o espacio?: ".ereg($patron02, $cadena05)."<br />";
?>

Recuerda que las expresiones regulares de tipo POSIX han quedado obsoletas desde la versión de PHP 5.3.0 !!

Si compruebas que no te funcionan bien las expresiones regulares asegúrate de guardar el archivo con codifición UTF-8.

Vea también: [ preg_match() ] - [ ereg() ]
Ejemplos PCRE:
<?php
// Cadenas de caracteres:
$cadena01 = "111-222-333";
$cadena02 = "C11-222-333";
$cadena03 = "111-222-3334";
$cadena04 = "11.222.333-X";
$cadena05 = "11.222.333-X4";
$cadena06 = "11.222.333-XB";
$cadena07 = "11.222.333-4";
// Patrones:
$patron01 = "/^[0-9]{3}\-[0-9]{3}\-[0-9]{3}$/"; // Teléfono válido
$patron02 = "/^[0-9]{2}\.[0-9]{3}\.[0-9]{3}\-[a-zA-Z]$/"; // NIF válido
echo "CADENA: [".$cadena01."]<br />";
echo "¿Teléfono válido?: ".preg_match($patron01, $cadena01)."<br />";
echo "¿NIF válido?: " .preg_match($patron02, $cadena01)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena02."]<br />";
echo "¿Teléfono válido?: ".preg_match($patron01, $cadena02)."<br />";
echo "¿NIF válido?: " .preg_match($patron02, $cadena02)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena03."]<br />";
echo "¿Teléfono válido?: ".preg_match($patron01, $cadena03)."<br />";
echo "¿NIF válido?: " .preg_match($patron02, $cadena03)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena04."]<br />";
echo "¿Teléfono válido?: ".preg_match($patron01, $cadena04)."<br />";
echo "¿NIF válido?: " .preg_match($patron02, $cadena04)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena05."]<br />";
echo "¿Teléfono válido?: ".preg_match($patron01, $cadena05)."<br />";
echo "¿NIF válido?: " .preg_match($patron02, $cadena05)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena06."]<br />";
echo "¿Teléfono válido?: ".preg_match($patron01, $cadena06)."<br />";
echo "¿NIF válido?: " .preg_match($patron02, $cadena06)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena07."]<br />";
echo "¿Teléfono válido?: ".preg_match($patron01, $cadena07)."<br />";
echo "¿NIF válido?: " .preg_match($patron02, $cadena07)."<br />";
echo "---------------------<p />";
?>
Ejemplos POSIX (el resultado es el mismo que en el caso anterior, salvo que no se mostrará nada en lugar de los ceros ya que ereg() devuelve false en esos casos):
<?php
// Cadenas de caracteres:
$cadena01 = "111-222-333";
$cadena02 = "C11-222-333";
$cadena03 = "111-222-3334";
$cadena04 = "11.222.333-X";
$cadena05 = "11.222.333-X4";
$cadena06 = "11.222.333-XB";
$cadena07 = "11.222.333-4";
// Patrones:
$patron01 = "^[0-9]{3}\-[0-9]{3}\-[0-9]{3}$"; // Teléfono válido
$patron02 = "^[0-9]{2}\.[0-9]{3}\.[0-9]{3}\-[a-zA-Z]$"; // NIF válido
echo "CADENA: [".$cadena01."]<br />";
echo "¿Teléfono válido?: ".ereg($patron01, $cadena01)."<br />";
echo "¿NIF válido?: " .ereg($patron02, $cadena01)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena02."]<br />";
echo "¿Teléfono válido?: ".ereg($patron01, $cadena02)."<br />";
echo "¿NIF válido?: " .ereg($patron02, $cadena02)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena03."]<br />";
echo "¿Teléfono válido?: ".ereg($patron01, $cadena03)."<br />";
echo "¿NIF válido?: " .ereg($patron02, $cadena03)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena04."]<br />";
echo "¿Teléfono válido?: ".ereg($patron01, $cadena04)."<br />";
echo "¿NIF válido?: " .ereg($patron02, $cadena04)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena05."]<br />";
echo "¿Teléfono válido?: ".ereg($patron01, $cadena05)."<br />";
echo "¿NIF válido?: " .ereg($patron02, $cadena05)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena06."]<br />";
echo "¿Teléfono válido?: ".ereg($patron01, $cadena06)."<br />";
echo "¿NIF válido?: " .ereg($patron02, $cadena06)."<br />";
echo "---------------------<p />";
echo "CADENA: [".$cadena07."]<br />";
echo "¿Teléfono válido?: ".ereg($patron01, $cadena07)."<br />";
echo "¿NIF válido?: " .ereg($patron02, $cadena07)."<br />";
echo "---------------------<p />";
?>

Si compruebas que no te funcionan bien las expresiones regulares asegúrate de guardar el archivo con codifición UTF-8.

Recuerda que las expresiones regulares de tipo POSIX han quedado obsoletas desde la

Vea también: [ preg_match() ] - [ ereg() ]