El Codiguero
Programando para la wé

Avatar de alvlin Publicado por alvlin, el 04/11/2008
Categorías: PHP, Programación

Expresiones regulares con PHP - POSIX

Nota: Como texto a analizar se utilizará esta página, que es un trozo conveniente de esta otra. Se eligió este texto por ser repetitivo y sencillo de comprender. Para analizarlo, se utilizará el siguiente patrón:
([0-9]{4}) ([A-Za-z]+) ([0-9]{2}): <a href="([^"]+)">(.*?)</a><br>

Introducción

PHP incluye soporte para expresiones regulares en el núcleo mismo del lenguaje, no se requieren extensiones para habilitarlo. Se soporta por defecto tanto la sintaxis POSIX (funciones ereg*) como la sintaxis PERL (funciones preg*).

Tradicionalmente se prefiere el uso de la sintaxis de Perl, en el entendido de que las funciones correspondientes tienen un mejor rendimiento que sus homólogas POSIX; sin embargo esto varía caso a caso según el tipo de patrón que se utilice. Si el rendimiento es crítico, se deben probar ambos tipos de patrones y comparar sus resultados.

Como mencionaba en una parte anterior de esta serie (Tipos de coincidencias y referencias), las funciones de expresiones regulares se separan en tres grupos: coincidencia de texto, reemplazo de texto, y separación de cadenas; siendo esta última la opción menos usada.

Funciones de Expresiones Regulares POSIX

Las funciones que PHP provee para utilizar expresiones regulares con sintaxis POSIX son:

Coincidencia de texto

ereg y eregi son las funciones encargadas de comparar una cadena de texto contra un patrón. La diferencia entre ambas es que eregi no diferencia entre mayúsculas y minúsculas. Esta característica la hace un poco más práctica, a la vez que un poco más lenta.

La sintaxis de ambas funciones es:

int ereg ( string $patron , string $cadena [, array $partes ] )

El valor retornado es un valor verdadero si se encontró alguna coincidencia, o falso si no se encontró ninguna. En caso de que el patrón contenga paréntesis, los datos se capturarán en el vector $partes, de forma tal que el trozo de la cadena que coincide con el patrón se guarda en el índice cero, el trozo capturado por el primer juego de paréntesis se guardará en el índice 1, el trozo capturado por el segundo juego se guardará en el índice 2, y así sucesivamente.

Ejemplo

He aquí un ejemplo de uso:

<?php define('ARCHIVO', 'ejemplo.txt'); define('PATRON', '([0-9]{4}) ([A-Za-z]+) ([0-9]{2}): <a href="([^"]+)">([^<]+)</a><br>'); $archivo = file_get_contents( ARCHIVO ); $res = ereg( PATRON, $archivo, $partes ); if ($res !== false) { print_r($partes); } ?>

Este código carga el contenido del archivo y le aplica el patrón. El resultado será el siguiente:

Array ( [0] => 2008 November 16: Anticrepuscular Rays Over Colorado [1] => 2008 [2] => November [3] => 16 [4] => ap081116.html [5] => Anticrepuscular Rays Over Colorado )

Como puede verse, el índice cero del vector contiene la coincidencia completa, es decir, todo el texto que coincidió con el patrón. A partir del índice 1, se almacenan los trozos de texto que coincidieron con cada juego de paréntesis en el patrón.

El problema con esta función es que solamente captura la primera coincidencia. Por esto, en vez de devolver todos los enlaces del archivo, la salida de el código anterior contiene solamente la primera coincidencia, y no todas. Este es otro de los motivos por los cuales se utilizan las funciones compatibles con Perl: una de ellas sirve para capturar todas las coincidencias del patrón sobre un texto (preg_match_all)

Reemplazo de texto

El reemplazo de texto se logra con ereg_replace. Se puede hacer uso de las referencias para vincular al contenido capturado por los paréntesis.

Por ejemplo, puede sustituirse el enlace por un listado del día y el título:

define('ARCHIVO', 'ejemplo.txt'); define('PATRON', '([0-9]{4}) ([A-Za-z]+) ([0-9]{2}): <a href="([^"]+)">([^<]+)</a>'); $archivo = file_get_contents( ARCHIVO ); $res = ereg_replace( PATRON, 'Imagen del día \\3 de \\2: \\5', $archivo );

Imagen del día 16 de November: Anticrepuscular Rays Over Colorado Imagen del día 15 de November: Arp 273 Imagen del día 14 de November: Fomalhaut b Imagen del día 13 de November: A Bubble in Cygnus Imagen del día 12 de November: Phoenix and the Holy Cow Imagen del día 11 de November: The Cosmic Web of the Tarantula Nebula Imagen del día 10 de November: Our Galaxy's Central Molecular Zone Imagen del día 09 de November: Two Black Holes Dancing in 3C 75 Imagen del día 08 de November: On the Trail of 2008 TC3 Imagen del día 07 de November: Cygnus Trio Imagen del día 06 de November: A Sharper View of a Hazy Giant Imagen del día 05 de November: Seventeen Hundred Kilometers Above Enceladus Imagen del día 04 de November: The Double Ring Galaxies of Arp 147 from Hubble Imagen del día 03 de November: A Spectacular Rayed Crater on Mercury Imagen del día 02 de November: Spicules: Jets on the Sun Imagen del día 01 de November: A Spectre in the Eastern Veil

División de cadenas

Para dividir cadenas PHP incluye la función explode(), que divide una cadena en trozos utilizando otra cadena (que se le pasa como parámetro) como separador.
El problema con explode es que toma una cadena fija, por lo que en ocasiones puede no tener la flexibilidad necesaria.

La función split() (y spliti(), la versión que no distingue entre mayúsculas y minúsculas) funciona de forma similar a explode, pero en vez de utilizar una cadena fija como separador utiliza una expresión regular.

Cualquiera que haya utilizado la función explode sabe cómo se utiliza split, ya que ambas se utilizan de forma similar. Recomiendo ver las páginas del manual de ambas funciones para obtener ejemplos de uso.

  • Digg
  • del.icio.us
  • Meneame
  • Reddit
  • Technorati
  • StumbleUpon
  • Facebook
  • LinkedIn
  • MySpace
  • Yahoo! Buzz
  • YahooMyWeb

» Si te pareció interesante, dejá un comentario...



Todo el contenido de este sitio está bajo una licencia de Creative Commons.

Campaña AnyBrowser | XHTML 1.0 Válido | CSS 2 Válido | WAI A

Diseño creado por alvlin. Sitio basado en WordPress