domingo, 5 de septiembre de 2010

Introducción a las Expresiones Regulares.

Hola a todos
Las expresiones regulares acompañan a los programadores desde hace mucho tiempo, se comenzó a hablar de ellas en Teoría de la información desde el año 1950, y desde entonces han supuesto una potente forma de procesar textos basada en patrones de búsqueda.
Aún así muchas veces es una parte del desarrollo que pasa desapercibida por lo que he decidido dedicarle algo de tiempo y explicaros sus orígenes, historia, implementaciones y gran funcionalidad, estoy seguro que os podrán sacar de más de un aprieto.


Pero… ¿Que son las Expresiones regulares?

Una expresión regular, también llamada patrón, es una expresión que define de manera genérica un conjunto de cadenas, de las que conocemos su estructura básica pero no conocemos cada uno de los caracteres que pueden componerlas.
Por poner un ejemplo, pensemos en una lista de elementos: Casa, Caza, Caasa, podríamos describir todos estos elementos con la expresión regular o patrón [ Ca(a?|s|z)a ], que identificaría las 3 cadenas antes indicadas, más adelante analizaremos más a fondo este patrón para que comprendáis su significado.

Historia

Los orígenes de las expresiones regulares se encuentran en la teoría de autómatas y la teoría de lenguajes formales, en 1950 el matemático Stephen Cole Kleene describió estos modelos usando su notación matemática llamada Regular Sets, y adaptados posteriormente al editor ed de UNIX, para más tarde ser usadas en expr, AWK, Emacs, vi y lex.
El uso de expresiones regulares en modelado de datos e información estructurada comenzó en 1960 y se expandió considerablemente en 1980. El núcleo del standard Lenguaje de especificaciones estructuradas son las expresiones regulares.

Expresiones Regulares en .NET

.NET incluye un motor de expresiones regulares desde su primera versión, que no ha sufrido cambios importantes y es uno de los mejor implementados que podemos encontrar.
Para usar expresiones regulares en nuestra aplicación simplemente debemos importar el namespace System.Text.RegularExpressions al inicio de nuestra clase:

Imports System.Text.RegularExpressions

Class MainWindow

End Class

Una vez hecho esto podremos acceder a la clase RegEx, que representa una instancia del motor de expresiones regulares de .NET, podemos usar esta clase para buscar rápidamente una subcadena dentro de una gran cantidad de texto o para extraer, editar, reemplazar o eliminar subcadenas de texto.

Para ello, primero debemos definir el patrón o expresión que queremos buscar. Para esto las expresiones regulares cuentan con todo un ejercito de definiciones que nos ayudan a indicar el texto que queremos considerar una coincidencia:


DefiniciónDescripción
|ó.
^Inicio de la línea.
$Fin de la línea.
\AInicio de la cadena.
\ZFin de la cadena.
\bInicio / Fin de palabra.
\BNo al inicio o fin de palabra.
*Buscar el dígito o letra anterior 0 ó más veces.
?Buscar el dígito o letra anterior 0 ó 1 vez.
+Buscar el dígito o letra anterior al menos 1 vez.
{n}Buscar exactamente el contenido de las llaves.
{n,m}Buscar todas las coincidencias entre n y m.
{n,}Buscar desde n en adelante.
\u0000 - \uFFFFBuscar el caracter unicode.
?<nombre>Expr.RegularAsignar un nombre al grupo de captura.

Esta es una pequeña lista de los elementos del lenguaje de las expresiones regulares, puedes encontrar una referencia completa en MSDN, aquí.

Con esto, pongamos un ejemplo práctico, imaginad que estáis analizando el texto de un archivo html y queréis encontrar todas las referencias a imágenes jpg y almacenarlas en una lista de cadenas para descargarlas posteriormente, sería tan sencillo como hacer esto:

(nota: esto es solo un ejemplo y bajo ciertas condiciones controladas, no identificaría correctamente todas las imágenes en un html real, es solo una muestra)


Dim Patron As String = "src='?<imagen>(http.*jpg)'\s+"
Dim Expresion As New Regex(Patron, RegexOptions.IgnoreCase)
Dim ListaImagenes As New List(Of String)

For Each Coincidencia As Match In Expresion.Matches(InputText)
ListaImagenes.Add(Coincidencia.Groups("imagen").Value)
Next

Como podéis ver es realmente sencillo usar expresiones regulares, son muy útiles para validación de entrada de texto, podéis definir varios patrones “no permitidos” y comprobar el texto que ha introducido el usuario en busca de ellos, por ejemplo podéis buscar un patrón SQL para evitar SQL Injection en aplicaciones Web o un patrón con el tipo de texto que el usuario debe introducir para verificar que el dato es correcto.

He preparado un pequeño programa en VB.NET y WPF que os permite cargar un archivo de texto e introducir una expresión regular a buscar en ese texto y os devuelve todas las coincidencias encontradas:


Captura

Conclusión


Bueno, las expresiones regulares son tan antiguas como la informática misma, pero son un recurso muy valioso hoy en día, puesto que nos ofrecen una herramienta inestimable para validar, corregir y extraer información de archivos sin formato predefinido, que de otra forma nos darían dolores de cabeza.

Espero que os haya gustado tanto leer este artículo como a mi escribirlo.

Por si tenéis alguna dificultad, a parte por supuesto de poder contactar conmigo tanto dejando mensajes, como en mi twitter, como en msdn o a mi email directamente, os dejo el proyecto completo para descarga.

Y recordad, con un simple comentario, podéis hacer feliz a un pequeño bloguero :)

Muchas gracias por leerme y Happy Coding!

5 comentarios:

  1. No te acostarás sin saber una cosa más . Y hoy si que me puedo ir tranquilo a la cama. Si que he aprendido algo muy interesante con esta entrada. ;-)

    ResponderEliminar
  2. Hola pajarito sin cola ;-)

    Estaba pensando... malo, malo ;-).
    El caso es que me preguntaba si podría emplear las expresiones regulares para obtener todos los controles (por ejemplo textblock) que están contenidos en un grid y que en su nombre tengan un caracter particular. Te hablo desde Silverlight.

    Un saludo,

    ResponderEliminar
  3. Hola Corsario

    Para eso podrias usar mejor los arboles de WPF, (el ultimo articulo que he publicado) y simplemente buscar si existe ese caracter en el nombre de cada objeto devuelto.

    Un gran saludo

    ResponderEliminar
  4. y ¿cuál es la aplicación de las expresiones regulares en el análisis de textos históricos?

    es que busco y busco y nada:(

    graciaas;)

    ResponderEliminar
  5. una preguntitaa...podrias deirme algo acerca de este tema?

    la expresiones regulares y su aplicacion en el analisis de textos historicos.

    graciaas;)

    ResponderEliminar