PHP tiene dos conjuntos distintos de funciones relacionadas con expresiones regulares, llamadas POSIX y PCRE.
Las funciones "PCRE" son "PERL Compatible", es decir, similares a las funciones nativas Perl, aunque con ligeras diferencias. Son bastante mas poderosas que las funciones POSIX, y correlativamente mas complejas.
POSIX
Incluye seis funciones diferentes. Como nota común, pasas primero el patrón (la expresión a buscar) y como segundo argumento la cadena a comparar
ereg confronta la cadena con el patrón de búsqueda y devuelve TRUE o FALSE segun la encuentre.
eregi como la anterior, SIN distinguir entre mayusculas-minusculas
<?php
ereg ("^am", "america"); // TRUE
$es_com = ereg("(.)(com$)",$url);
// buscamos dos subpatrones en $url. El primero es
// un punto (literal) y por eso va escapado con la barra.
// el segundo subpatron también literal busca la secuencia "com"
// al final de una palabra.
?>
ereg_replace: Busca cualquier ocurrencia del patrón en la cadena y la reemplaza por otra.
eregi_replace: Como la anterior pero sin distinguir mayusculas minusculas:
patrón, reemplazo, cadena a confrontar
<?php
$cadena = ereg_replace ("^am", "hispano-am", "america"); // $cadena = hispano-america
?>
split() divide una cadena en piezas (que pasan a un array) usando expresiones regulares:
spliti() como el anterior, sin diferenciar Mayusculas-minusculas
Es básicamente igual que explode, pero utilizando expresiones regulares para dividir la cadena, en lugar de expresiones literales
<?php
$date = "24-09-2003";
list($month, $day, $year) = split ('[/.-]', $date);
?>
Almacenando los resultados con ereg
Podemos pasar un patrón con subpatrones agrupados en parentesis. Si en este caso usamos ereg, podemos añadir un tercer parámetro: el nombre de un array que almacenará las ocurrencias; $array[1] contendrá la subcadena que empieza en el primer paréntesis izquierdo; $array[2] la que comienza en el segundo, etc. $array[0] contendrá una copia de la cadena.
<?php
$date = "24-09-2003"; // pasamos una fecha formato dd-mm-yyyy
if (ereg ("([0-9]{1,2})-([0-9]{1,2})-([0-9]{4})", $date, $mi_array)) {
echo "$mi_array[3].$mi_array[2].$mi_array[1]";
// coincide. Lo mostramos en orden inverso porque somos asi : )
} else {
echo "Invalid date format: $date"; // no coincide
}
?>
Almacenando los resultados con ereg_replace: backreferences
De forma muy similar a ereg, las funciones de búsqueda y sustitución ereg_replace y eregi_replace pueden almacenar y reutilizar subocurrencias (subpatrones encontrados en la cadena).
La principal diferencia es la forma de llamar las subocurrencias almacenadas, ya que necesitamos utilizar la barra invertida: \0, \1, \2, y asi hasta un máximo de 9.
La primera referencia \0 hace referencia a la coincidencia del patrón entero; el resto, a las sub-ocurrencias de los sub-patrones, de izquierda a derecha.
Por ejemplo vamos a usar esta capacidad para convertir una cadena que muestra una url en un enlace:
<?php
$url = "la página blasten.com (http://www.blasten.com)";
$url = ereg_replace ("(http|ftp)://(www.)?(.+).(com|net|org)","<a href="\0 ">\3</a>",$url);
echo $url;
?>
Funciones PCRE
Las funciones PCRE son "perl-compatibles". Perl es uno de los lenguajes de programación con mejor motor de expresiones regulares, y además es muy conocido. Esta librería es utilizada (con distintas variantes) no solo por Perl, sino por el propio PHP y tambien en otros entornos, como el server Apache, Phyton o KDE.
Las funciones de expresiones regulares PCRE de PHP son mas flexibles, potentes y rápidas que las POSIX.
Prácticamente no existe ninguna diferencia sintáctica entre un patrón PCRE o POSIX; muchas veces son intercambiables. Naturalmente existe alguna diferencia. La mas evidente, que nuestro patrón deberá estar marcado en su principio y final unos delimitadores, normalmente dos barras:
/patron/
DelimitadoresSe puede usar como delimitador cualquier carácter especial (no alfanumerico) salvo la barra invertida .
La costumbre mas extendida es, como hemos visto, usar la barra /, sin embargo, si posteriormente vamos a necesitar incluir el mismo caracter delimitador en el patrón, tendremos que escaparlo, por lo que tiene sentido usar en esos casos unos delimitadores distintos: (), {}, [], o < >
ModificadoresSe colocan despues del patrón:
<?php
m // multilínea. Si nuestra cadena contiene varias lineas físicas (n)
// respeta esos saltos de línea, lo que significa, por ejemplo,
// que las anclas ^ $ no se aplican al principio y final de la
// cadena, sino al principio y final de cada linea
s // El metacaracter . representa cualquier carácter menos el de
// nueva linea. Con el modificador "s" tambien representa la nueva linea.
i // Se confronta el patrón con la cadena ignorando Mayusculas minusculas
x // ignora espacios (salvo que esten escapados o incluidos
// específicamente dentro del rango de búsqueda. Ignora cualquier caracter
// despues de almohadilla (#) hasta nueva línea. Sirve para incluir
// comentarios y hacer mas legible el patrón.
e // solo en preg_replace. Evalua las ocurrencias como código php antes
// de realizar la sustitución.
A // El patrón es forzado a ser "anclado", esto es, solo existirá una
// ocurrencia si es al inicio de la cadena.
E // el carácter $ en el patrón casará con el fin de la cadena.
// Sin este modificador, $ casa tambien con el carácter inmediatamente
// antes del de una nueva línea.
U // Este modificador invierte la "codicia" de los cuantificadores.
// Si aplicamos U, * se convierte en perezoso (lazy) y *? vuelve a su
// comportamiento normal.
// Un cuantificador es "codicioso" (greedy) cuando intenta capturar todas
// las ocurrencias posibles, y perezoso (lazy) cuando captura la
// ocurrencia mas corta.
?>
Delimitadores de palabraEn las funciones PCRE puedes usar b que indica el comienzo y fin de una palabra (o mejor, de una secuencia alfanumerica):
/bpatronb/
B, por el contrario, se refiere a un patrón que no está al comienzo o fin de una palabra.
Las expresiones regulares que usan cuantificadores tienden a ser todo lo codiciosas que les sea permitido, siempre que respeten el patrón a seguir. Con el modificador U se invierte este comportamiento.
En modo codicioso el patrón casará todas las ocurrencias que pueda, mientras que en modo lazy o ungreedy, casará solo la mas corta posible (e).
Advierte que las dos soluciones son correctas.
patrón: /http://.*.(com|net|org)/esto es un link: http://www.abc.com y este otro mas: http://www.blah.com
patrón: /http://.*.(com|net|org)/Uesto es un link: http://www.abc.com y este otro mas: http://www.blah.com
Las funciones
Tenemos cinco funciones PCRE:
preg_match()
preg_match_all()
preg_replace()
preg_split()
preg_grep()
preg_match busca el patrón dentro de la cadena, devolviendo TRUE si es hallado:
patron, cadena [,array de resultados]
Si indicamos el tercer parámetro, tendremos los resultados en un array; $array[0] contendrá la ocurrencia del patrón; $array[1] tendrá la cadena que case con el primer subpatrón y así sucesivamente.
preg_match_all encuentra todas las ocurrencias del patrón en la cadena.
patron, cadena, array de patrones, orden
Si proporcionamos el cuarto parámetro, colocara las ocurrencias en un array siguiendo el orden indicado.
preg_replace busca y reemplaza el patrón en la cadena. Tanto el patrón como la sustitución pueden pasarse en array, y pueden contener expresiones regulares.
Puede tambien especificarse un límite máximo de ocurrencias.
preg_split opera como split aunque tambien puedes pasarle expresiones regulares
preg_grep busca el patrón dentro de un array, y devuelve otro array con las ocurrencias.
patron, array.