Backreference en expresiones regulares (I)

Estos días me ha tocado pelearme con algo que desconocía completamente en expresiones regulares y que me ha parecido muy interesante, además de ayudarme enormemente. Se trata del backreference, o de cómo hacer referencia a elementos de la expresión regular dentro de la propia expresión regular o dentro de un remplazo con expresiones regulares.

Si en el contenido de una expresión regular se pone \n, se sustituirá automáticamente por el valor del grupo correspondiente, pudiendo tener así “variables” dentro de una expresión regular.

La mejor forma de entender cómo funciona es con un ejemplo práctico y para mi, real.

En un documento .php tengo que buscar todos los elementos de tipo texto y extraer su contenido. Éstos elementos vienen definidos por la siguiente expresión regular:

<(div|h1|h2|h3|span) class='(title|subtitle|txt)'.*?>([\s\S]+?)</(div|h1|h2|h3|span)>

Hasta aquí todo correcto, e incluso sencillo, ya que la expresión regular no es demasiado complicada y el contenido se extrae fácilmente con el grupo 3. Pero el problema viene dado por la propia construcción de una página HTML.

<div class='txt'>Texto de prueba</div>

En un texto como este no hay ningún problema.

<div class='txt'><span>Texto</span> de prueba</div>

Pero aquí ya se ha liado una gorda porque la expresión regular obtendría como resultado en el grupo 3 “<span>Texto“, lo que obviamente, está mal.

¿Cómo conseguir el resultado deseado? Que si se encuentra una coincidencia que empieza con una etiqueta span esa coincidencia termine con un /span, pues recurriendo al backreference

<(div|h1|h2|h3|span) class='(title|subtitle|txt)'.*?>([\s\S]+?)</\1>

Lo que sucede en esta expresión regular es que cuando se encuentre una coincidencia, el \1 se sustituirá por la coincidencia del grupo 1, de esta forma se consigue lo que buscaba desde el principio y la expresión regular ya sí que funciona correctamente.

Anuncios
  1. No trackbacks yet.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: