Categoría: Programación


Hace algunas semanas me encontré por casualidad Microsoft Small Basic, una implementación del paradigma de programación para niños que utiliza una tortuga en pantalla a la cual se le dan órdenes tales como moverse hacia adelante o rotar una cantidad específica de grados.

Logo, otra implementación de este paradigma, fue la forma en la cual yo entré en el mundo de la programación allá por 1986, hace ya 24 años. Debido a esto encontrar Small Basic me llenó de gratos recuerdos y desde entonces he dedicado algunos de mis ratos libres a jugar de nuevo con este paradigma tan interesante y motivador, que me llevó a encontrar mi vocación hace tanto tiempo.

Una de las principales razones por las cuales la Tortuga es una de las mejores formas de introducir a los niños al mundo de la programación es que los resultados del código escrito se pueden ver en pantalla de forma rápida e inmediata y las permutaciones que se pueden hacer al código dan para horas de entretenimiento infantil. Adicionalmente, no es necesario aprender muchos conceptos teóricos de programación antes de obtener resultados agradables.

En una de estas sesiones de juego con la tortuga, me dí a la tarea de crear un algoritmo que me permitiera simular cierto grado aleatoriedad en el resultado visual, pero sin sacrificar la belleza del mismo. Para esto introduje niveles de aleatoriedad controlados dentro del marco de ciertas reglas. El resultado sigue siendo aleatorio (y sorpresivo), y por lo tanto cada uno de los patrones generados tiene una muy baja probabilidad de repetirse nuevamente; sin embargo, a pesar del aparente caos reinante en los patrones, estos muestran orden como un todo, lo cual los hace en su mayoría atractivos al ojo humano.

Algunos de los resultados del algoritmo se presentan a continuación:

 

Si desea ver más resultados, puede descargar Small Basic y utilizar el algoritmo para generarlos:

seed = Math.GetRandomNumber(24)
goal = seed * 15
maxSteps = Math.GetRandomNumber(48)
steps = Math.GetRandomNumber(maxSteps) + 1
For j = 1 To steps
  angles[j] = Math.GetRandomNumber(goal)
EndFor

distance = Math.GetRandomNumber(100)

Turtle.Speed = 10
GraphicsWindow.PenColor = GraphicsWindow.GetRandomColor()

For i = 1 To 50
  For j = 1 To steps
    angle1 = angles[j]
    angle2 = goal – angle1 
    Turtle.Turn(angle1)
    Turtle.Move(distance)
    Turtle.Turn(angle2)
    Turtle.Move(distance)
  EndFor
EndFor

Turtle.Hide()

Para habilitar la integración entre Expression Blend 3 y Team Foundation Server, es necesario bajar e instalar un parche que se encuentra en la siguiente ubicación:
 
 
Después de la instalación Blend realizará el "check out" de los archivos de forma automática cuando estos son modificados, lo cual ahorra mucho tiempo al trabajar sobre archivos que están bajo control de versiones de código usando TFS.
En estos días he estado modificando un proyecto bastante grande que hemos retomado después de casi un año de inactividad. Después de varios días llego el momento de crear la primera prueba unitaria (unit test) para las clases agregadas.
 
Para mi sorpresa, cuando abrí el cuadro de diálogo correspondiente este se desplegó vacío y no me daba ninguna opción.
 
Después de realizar una rápida búsqueda, descubrí que la causa era una pulga que se presentaba cuando uno de los proyectos no producían como salida un esamble (assembly, .dll), como es el caso de los proyectos de bases de datos y Silverlight.
 
En este caso el problema era un proyecto de base de datos (VSTS DBE GDR2).
 
Afortunadamente Microsoft ya había producido un parche para esta pulga, el cual puede ser descargado desde esta dirección:
 
 
Después de bajarlo e instalarlo la generación de pruebas volvió a funcionar adecuadamente.
 
 
Estos días he desarollado algunos controles de WPF en librerías externas al proyecto principal, y en el proceso me dí cuenta de que en algunos casos, al abrir el proyecto con Blend, no era posible editar los controles en la vista de diseño, sino que se habrían por defecto en la vista de código y no permitían cambiar de vista.
 
Me dí cuenta de que los proyectos creados bajo la categoría "WPF Control Library" si permitían abrir los controles en vista de diseño, mientras los creados bajo la categoría "Class Library" eran los que presentaban el problema.
 
Entonces me dí a la tarea de encontrar que era lo que los diferenciaba. Creé un proyecto de cada tipo usando el mismo nombre y luego utilicé el comparador de TFS para comparar los archivos .csproj.
 
Además de algunas referencias a librerías adicionales, el proyecto de libraría de controles contenía las dos líneas siguientes:
 
    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    <WarningLevel>4</WarningLevel>
Procedí a abrir el archivo .csproj del proyecto de librería de clases usando Notepad y le agregué las dos líneas faltantes. Luego lo abrí en Blend y comprobé que efectivamente era posible abrir los controles en la vista de diseño después de efectuar este cambio.
Como nos informa Scott Gu el día de hoy en su blog, a partir de la versión 3.5 el marco de trabajo .NET de Microsoft tendrá código abierto y será posible para los programadores de cualquiera de los lenguajes del marco de trabajo acceder a la fuente mediante las herramientas de depuración, de manera que sea posible seguir la ejecución del código incluso dentro de las librerías de .NET.
 
Esto es una excelente noticia para todos los programadores que utilizamos alguno de los lenguajes de este marco de trabajo.
 
Si se ha trabajado lo suficiente con VBA (específicamente con Excel), y se quiere construir una extensión de aplicación robusta; es muy probable que en algún momento se haya tenido la necesidad de convertir la representación numérica de una columna en su representación como cadena de caracteres (osea, de 1 a A, de 104 a DA, etc.) Esto se puede conseguir fácilmente utilizando la siguiente función:
Public Function GetColumnCharacterRepresentation _
  (ByVal column As Integer) As String
  Dim intFirstCharacter
  intFirstCharacter = Int(column / 26)
  Dim intLastCharacter
  intLastCharacter = IIf(intFirstCharacter = 0, _
    CInt(column Mod 26), CInt(column Mod 26) + 1)
  Dim strFirstCharacter As String
  strFirstCharacter = IIf(intFirstCharacter > 0, _
    Chr(intFirstCharacter + 64), "")
  Dim strLastCharacter As String
  strLastCharacter = Chr(intLastCharacter + 64)
  GetColumnCharacterRepresentation = strFirstCharacter _
   & strLastCharacter
End Function

Con los metacaracteres que hemos aprendido hasta el momento, es posible efectuar múltiples tipos de búsquedas y validaciones como ya hemos visto en los ejemplos de las entregas anteriores. Sin embargo, los metacaracteres que veremos en esta entrega son los que probablemente aportan más flexibilidad y funcionalidad a las expresiones regulares: Los caracteres de repetición.

Las llaves "{}"

Comúnmente las llaves son caracteres literales cuando se utilizan por separado en una expresión regular. Para que adquieran su función de metacaracteres es necesario que encierren uno o varios números separados por coma y que estén colocados a la derecha de otra expresión regular de la siguiente forma: "\d{2}" Esta expresión le dice al motor de búsqueda que encuentre dos dígitos contiguos. Utilizando esta formula podríamos convertir el ejemplo "^\d\d/\d\d/\d\d\d\d$" que nos servía para validar un formato de fecha en "^\d{2}/\d{2}/\d{4}$" para una mayor claridad en la lectura de la expresión.

Aunque esta forma de encontrar elementos repetidos es muy útil, algunas veces no sabemos cuantas veces se repite lo que búscamos o su grado de repetición es variable. En estos casos los siguientes metacaracteres no son útiles.

El asterisco "*"

El asterisco nos sirve para encontrar algo que se encuentra repetido 0 o más veces. Osea, utilizando la expresión "[a-zA-Z]\d*" nos servirá para encontrar tanto "H" como "H1", "H01", "H100" y "H1000", osea, una letra seguida de un número indefinido de caractéres. Es necesario tener cuidado con el comportamiento del asterisco, ya que este por defecto trata de encontrar la mayor cantidad posible de caracteres que correspondan con el patrón que buscamos. De esta forma si utilizamos "\(.*\)" para encontrar cualquier cosa que se encuentre entre paréntesis y lo aplicamos sobre el texto "Ver (Fig. 1) y (Fig. 2)" esperaríamos que el motor de búsqueda encuentre los textos "(Fig. 1)" y "(Fig. 2)", sin embargo nos sorprenderemos al ver que en su lugar encontrará el texto "(Fig. 1) y (Fig. 2)". Esto sucede porque el asterísco le dice al motor de búsqueda que llene todos los espacios posibles entre dos paréntesis, y ese es el resultado que obtenemos. Si queremos obtener el resultado deseado debemos utilizar el asterisco en conjunto con el signo de pregunta de la siguiente forma: "\(.*?\)" Esto es equivalente a decirle al motor de búsqueda "Encuentre un paréntesis de apertura y luego encuentre cualquier caracter repetido hasta que encuentre un paréntesis de cierre".

El signo de suma "+"

Nos sirve para encontrar algo que se encuentre repetido 1 o más veces. A diferencia del asterisco, la expresión "[a-zA-Z]\d+" encontrará "H1" pero no encontrará "H". También es posible utilizar este metacaracter en conjunto con el signo de pregunta para limitar hasta donde queremos que se efecúe la repetición.

En la entrega anterior hablamos de que los paréntesis redondos establecen un "punto de referencia" para el motor de búsqueda. Estos puntos se denominan grupos y pueden ser anónimos o nominales. A continuación veremos en detalle como utilizar los grupos.

Grupos anónimos

Los grupos anónimos se establecen cada vez que encerramos una expresión regular en paréntesis redondos, por lo que la expresión "<([a-zA-Z]\w*?)>" define un grupo anónimo que tendrá como resultado que el motor de búsqueda almacenará una referencia al texto que coresponda a la expresión encerrada entre los paréntesis.

Pero como podemos utilizar los grupos que establecemos? La forma más inmediata de utilizar los grupos es dentro de la misma expresión regular, lo cual se realiza utilizando la barra inversa "\" seguida del número del grupo al que queremos hacer referencia de la siguiente forma: "<([a-zA-Z]\w*?)>.*?</\1>" Esta expresión regular nos ayudará a encontrar tanto "<font>Esta</font>" como "<B>prueba</B>" en el texto "<font>Esta</font> es una <B>prueba</B>" a pesar de que la expresión no contiene los literales "font" y "B".

Otra forma de utilizar los grupos es en el lenguaje de programación que estemos utilizando. cada lenguaje tiene una forma de distinta de acceder a los grupos, pero como explicamos al principio de la serie explicaremos con detalle la forma utilizada por el .Net Framework, usando la sintáxis de C# (la cual puede facilmente adaptarse a VB.Net o cualquier otro lenguaje del Framework).

Para utilizar el motor de búsqueda del .Net Framework es necesario en primer lugar hacer referencia al espacio de nombres System.Text.RegularExpressions. Luego es necesario declarar una instancia de la clase Regex de la siguiente forma:

Regex _TagParser = new Regex("<([a-zA-Z]\w*?)>");

Luego asumiendo que el texto que queremos examinar con la expresión regular se encuentra en la variable "sText" podemos recorrer todas las instancias encontradas de la siguiente forma:

foreach(Match CurrentMatch in _TagParser.Matches(sText)){
   // —– Código extra aquí —–
}

Luego podemos utilizar la propiedad Groups de la clase Match para traer el resultado de la búsqueda:

foreach(Match CurrentMatch in _TagParser.Matches(sText)){
  String sTagName = CurrentMatch.Groups[1].Value;
}

Grupos nominales

Los grupos nominales son aquellos a los que les asignamos un nombre, dentro de la expresión regular para poder utilizarlos posteriormente. Esto se hace de forma diferente en los distintos motores de búsqueda, así que una vez más aqui explicaremos como hacerlo en el motor del .Net Framework.

Utilizando el ejemplo anterior podemos convertir "<([a-zA-Z]\w*?)>" en "<(?<TagName>[a-zA-Z]\w*?)>". Nótese el signo de pregunta y el texto "TagName" encerrado entre parentesis triangulares, seguido de este. Para utilizar este ejemplo en el .Net Framework utilizaríamos el siguiente código:

Regex _TagParser = new Regex("<(?<TagName>[a-zA-Z]\w*?)>");
foreach(Match CurrentMatch in _TagParser.Matches(sText)){
  String sTagName = CurrentMatch.Groups["TagName"].Value;
}

Es posible definir tantos grupos como sea necesario, de esta forma podemos hacer algo como: "<(?<TagName>[a-zA-Z]\w*?) ?(?<Attributes>.*?)>" para encontrar no solo el nombre del tag HTML sino tambien sus atributos de la siguiente forma:

Regex _TagParser = new Regex("<(?<TagName>[a-zA-Z]\w*?) ?(?<Attributes>.*?)>");
foreach(Match CurrentMatch in _TagParser.Matches(sText)){
  String sTagName = CurrentMatch.Groups["TagName"].Value;
  String sAttributes = CurrentMatch.Groups["Attributes"].Value;
}

Pero podemos ir mucho más allá:
"<?(?<TagName>[a-zA-Z][\w\r\n]*?) ?(?:(?<Attribute>[\w-\r\n]*?)=’?"?(?<Value>[\w-:;,\./= \r\n]*?)’?"? ?)>"
Esta expresión nos permite encontrar el nombre del tag, el nombre del atributo y su valor.

Sin embargo, una tag html puede tener más de un atributo. Este caso lo resolveríamos utilizando repetición de la siguiente forma:
"<?(?<TagName>[a-zA-Z][\w\r\n]*?) ?(?:(?<Attribute>[\w-\r\n]*?)=’?"?(?<Value>[\w-:;,\./= \r\n]*?)’?"? ?)*?>"

Y en el código la utilizariamos de la siguiente forma:

Regex _TagParser = new Regex("<?(?<TagName>[a-zA-Z][\w\r\n]*?) ?(?:(?<Attribute>[\w-\r\n]*?)=’?"?(?<Value>[\w-:;,\./= \r\n]*?)’?"? ?)*?>");
foreach(Match CurrentMatch in _TagParser.Matches(sText)){
  String sTagName = CurrentMatch.Groups["TagName"].Value;
  foreach(Capture CurrentCapture in CurrentMatch.Groups["Attribute"].Captures){
    AttributesCollection.Add(CurrentCapture.Value)
  }
  foreach(Capture CurrentCapture in CurrentMatch.Groups["value"].Captures){
    ValuesCollection.Add(CurrentCapture.Value)
  }
}

Aún más podríamos profundizar utilizando una expresión como esta:
"<?(?<TagName>[a-zA-Z][\w\r\n]*?) ?(?:(?<Attribute>[\w-\r\n]*?)=’?"?(?<Value>[\w-:;,\./= \r\n]*?)’?"? ?)*?>(?<Content>.*?)</\1>"

La cual nos permitiría encontrar el tag, sus atributos, valores y el contenido de esta, y todo con una sola expresión regular!!!!

Espero que les haya gustado esta cuarta entrega. En la próxima continuaremos estudiendo ejemplos y aplicaciones de las expresiones regulares en casos específicos.

No duden en enviarme sus dudas y comentarios al respecto, estaré dispuesto a ampliar la información dada según sea requerido.

En la segunda entrega de la serie iniciamos la lista de los caracteres especiales o "metacaracteres"; en esta entrega ampliaremos esta lista.

Los paréntesis cuadrados "[]"

La función de los paréntesis cuadrados en el lenguaje de las expresiones regulares es representar "clases de caracteres", osea, agrupar caracteres en grupos o clases. Son útiles cuando necesitamos buscar uno de un grupo de caracteres. Dentro de los paréntesis cuadrados es posible utilizar el guión "-" para especificar rangos de caracteres. Adicionalmente, los metacracteres pierden su significado y se convierten en literales cuando se encuentran dentro de los parentesis cuadrados. Por ejemplo, como vimos en la entrega anterior "\d" nos es útil para buscar cualquier caracter que represente un dígito. Sin embargo esta denominación no incluye el punto "." que divide la parte decimal de un número. Para buscar cualquier caracter que representa un dígito o un punto podemos utilizar la expresión regular "[\d.]". Como dijimos, dentro de los paréntesis cuadrados, el punto representa un caracter literal y no un metacaracter, por lo que no es necesario antecederlo con la barra inversa. El único caracter que es necesario anteceder con la barra inversa dentro de los parentesis cuadrados es la propia barra inversa. La expresión regular "[\dA-Fa-f]" nos permite encontrar dígitos hexadecimales. Los paréntesis cuadrados nos permiten también encontrar palabras aún si están escritas de forma errónea, por ejemplo, la expresión regular "expresi[oó]n" nos permite encontrar en un texto al palabra "expresión" aunque se haya escrito con o son acento. Es necesario aclarar que sin importar cuantos caracteres se introduzcan dentro del grupo por medio de los paréntesis cuadrados, el grupo solo le dice al motor de base de búsqueda que encuentre un solo caracter, osea, que "expresi[oó]n" no encontrará "expresioon" o "expresioón".

La barra "|"

Nos sirve para indicar una de varias opciones. Por ejemplo, la expresión regular "a|e" encontrará cualquier "a" o "e" dentro del texto. La expresión regular "este|oeste|norte|sur" nos permitirá encontrar cualquiera de los nombres de los puntos cardinales. La barra se utiliza comúnmente en conjunto con otros caracteres especiales como veremos más adelante.

El signo de dólar "$"

Representa el final de la cadena de caracteres o el final de la linea, si estamos utilizando el modo multi-linea. No representa un caractér en especial sino una posición. Si utilizamos la expresión regular "\.$" encontraremos todos los lugares donde un punto finalize la linea, lo que es útil para avanzar entre párrafos.

El acento circunflexo "^"

Este caractér tiene una doble funcionalidad, que difiere cuando se utiliza individualmente y cuando se utiliza en conjunto con otros caractéres especiales. Vamos a comentar en primer lugar su funcionalidad como caracter individual.
De manera similar que el signo de dólar "$" este caracter representa el inicio de la cadena, de forma que si utilizamos la expresión regular "^[a-z]" nos permitirá encontrar todos los párrafos que den inicio sin utilizar la letra mayúscula.
Cuando se utiliza en conjunto con los paréntesis cuadrados de la siguiente forma "[^\w ]" nos permite encontrar cualquier caracter que NO se encuentre dentro del grupo indicado. La expresión indicada nos permite encontrar, por ejemplo, cualquier caracter que no sea alfanumérico o un espacio, osea, busca todos los símbolos de puntuación y demás caracteres especiales.
La utilización en conjunto de los caracteres especiales "^" y "$" nos permite realizar validaciones en forma sencilla. Por ejemplo "^\d$" nos permite asegurarnos de que al cadena que deseamos verificar representa un único dígito, "^\d\d/\d\d/\d\d\d\d$" nos permite validar una fecha en formato corto, aunque no nos permite verificar si es una fecha válida, ya que 99/99/9999 también calza en este formato; esta validación también puede realizarse, como veremos más adelante.

Los paréntesis redondos "()"

De forma similar que los paréntesis cuadrados, los paréntesis redondos nos sirven para agrupar caracteres, sin embargo existen varias diferencias fundamentales entre los grupos establecidos por medio de parentesis cuadrados y los grupos establecidos por paréntesis redondos:

  • Los caracteres especiales conservan su significado dentro de los paréntesis redondos.
  • Los grupos establecidos con paréntesis redondos establecen una "etiqueta" o "punto de referencia" para el motor de búsqueda que puede ser utilizada posteriormente como veremos más adelante.
  • Utilizado en conjunto con la barra "|" nos permite hacer búsquedas opcionales. Por ejemplo la expresión regular "al (este|oeste|norte|sur) de" nos permite buscar textos que nos den indicaiones por medio de puntos cardinales, mientras que la expresión regular "este|oeste|norte|sur" encontraría "este" en la palabra "esteban".
  • Utilizado en conjunto con otros caracteres especiales de los que hablaremos posteriormente, permite obtener funcionalidad adicional.

El signo de pregunta "?"

El signo de pregunta tiene varias funciones dentro del lenguaje de las expresiones regulares. La primera de ellas es especificar que una parte de la búsqueda es opcional. Por ejemplo, la expresión regular "ob?scuridad" nos permite encontrar tanto "oscuridad" como "obscuridad". En conjunto con los parentesis redondos nos permite especificar que un conjunto mayor de caracteres es opcional; por ejemplo "Nov(\.|iembre|ember)?" nos permite encontrar tanto "Nov" como "Nov.", "Noviembre" y "November".
Como dijimos anteriormente los paréntesis redondos nos permiten establecer un "punto de referencia" para el motor de búsqueda, sin embargo, algunas veces, no queremos utilizarlos con este propósito, como en el ejemplo anterior "Nov(\.|iembre|ember)?". En este caso el establecimiento de este punto de referencia (que distcutiremos en futuras entregas) representa una inversión inútil de recursos por parte del motor de búsqueda. Para evitar esto podemos utilizar el signo de pregunta de la siguiente forma: "Nov(?:\.|iembre|ember)?". Aunque el resultado obtenido será el mismo, el motor de búsqueda no realizará una inversión inútil de recursos en este grupo, sino que lo ignorará. Cuando no sea necesario reutilizar el grupo, es aconsejable utilizar este formato.
De forma similar, podemos utilizar el signo de pregunta con otro significado: Los paréntesis redondos definen grupos "anónimos", sin embargo podemos utilizar el signo de pregunta en conjunto con los paréntesis triangulares "<>" para "nombrar" estos grupos de la siguiente forma: "^(?<Dia>\d\d)/(?<Mes>\d\d)/(?<Año>\d\d\d\d)$"; Con lo cual le decimos al motor de búsqueda que los primeros dos dígitos encontrados llevarán la etiqueta "Dia", los segundos la etiqueta "Mes" y los últimos cuatro dígitos llevarán la etiqueta "Año".

Nota: En futuras entregas veremos como utilizar los "puntos de referencia" establecidos por los paréntesis redondos, tanto los que se establecen en forma anónima, como los que se establecen con un determinado nombre.

A pesar de la complejidad y flexibilidad que nos dan los caracteres especiales que hemos estudiado hasta ahora, en su mayoría nos permiten encontrar solamente un caractér a la vez, o un grupo de caracteres a la vez. En la próxima entrega estudiaremos los últimos metacaracteres, que nos permiten establecer repeticiones.

Las expresiones regulares son un método por medio del cual se pueden realizar búsquedas dentro de cadenas de caracteres. Sin importar si estamos buscando dos caracteres en una cadena de 10 o si necesitamos encontrar todas las apariciones de un patrón definido de caracteres en un archivo de millones de caracteres, las expresiones regulares nos proporcionan una solución para nuestro problema. Adicionalmente, es importante decir, que un uso derivado de la búsqueda de patrones es la validación de un formato especifico en una cadena de caractedes dada, pero este es un tema que tocaremos más adelante.

Donde encontrar las expresiones regulares

Para poder utilizar las expresiones regulares es necesario tener acceso a un motor de búsqueda con la capacidad de utilizarlas. Podemos clasificar los motores disponibles en dos tipos: Motores para el programador y Motores para el usuario final.

Motores para el usuario final: Son programas que permiten realizar búsquedas sobre el contenido de un archivo o sobre un texto extraido y colocado en el programa. Están diseñados para permitir al usuario el uso de búsquedas avanzadas usando este mecanismo, sin embargo es necesario aprender a redactar expresiones regulares adecuadas para poder utilizarlos eficientemente. Estos son algunos de los programas disponibles:

  • grep: Programa del mundo Linux.
  • ProwerGrep: versión de grep para windows
  • RegexBuddy: Ayuda a crear las expresiones regulares en forma interactiva y luego le permite al usuario usarlas y guardarlas.
  • EditPad Pro: Permite realizar búsquedas con expresiones regulares sobre archivos y las muestra por medio de código de colores para facilitar su lectura y comprensión.

Motores para el programador: Algunas veces encontrar lo que queremos dentro de un archivo no es suficiente y es necesario automatizar el proceso de búsqueda de modo que sea posible utilizarlo muchas veces para un propósito específico. Es aquí donde se vuelve útil que la herramienta con la cual estamos programando nos permita el uso de expresiones regulares, para realizar nuestras búsquedas y validaciones. Estas son las herramientas de programación disponibles que ofrecen motores de búsqueda con soporte a expresiones regulares:

  • Java: Existen varias librerias hechas para java que permiten el uso de RegEx, y Sun planea dar soporte a estas desde el SDK
  • JavaScript: Me sorprendió bastante saber que a partir de la versión 1.2 (ie4+, ns4+) JavaScript tiene soporte integrado para expresiones regulares, lo que significa que las validaciones que se realizan normalmente en una página web podrían simplificarse grandemente si el programador supiera utilizar esta herramienta.
  • Perl: Es el lenguaje que hizo crecer a las expresiones regulares a lo que son hoy.
  • PCRE: Librería de ExReg para C, C++ y otros lenguajes que puedan utilizar librerias dll (VB6 por ejemplo).
  • PHP: Tiene dos tipos diferentes de expresiones regulares disponibles para el programador.
  • Python: Lenguaje de "scripting" popular con soporte a ExReg.
  • .Net Framework: En mi opinión la más poderosa herramienta para el uso de ExReg; no porque sea superior a los demás lenguajes mencionados en este campo, sino porque en conjunto con las demás librerías de clases base, provee un  conjunto inigualable de utilitarios para el programador.

Aunque hasta ahora no hemos profundizado en la estructura y la definición de las expresiones regulares, es importante que antes de tomarlas en cuenta como una opción viable para dar solución al problema que se tiene por delante, estemos seguros de que tendremos acceso al menos a una herramienta de cada tipo (una para el usuario final y otra para el programador) de modo que el proceso de creación de la solución para nuestro problema no se convierta en un dolor de cabeza o eventualmente en una pérdida de tiempo. Una vez se tiene a mano el lenguaje de programación elegido y el programa que apoyará el proceso de creación, podemos adentrarnos en el aprendizaje de este lenguaje tan útil y poderoso.

Una de las cosas que más me emocionan en la vida es el poder aprender. Y gracias al proyecto que estoy desarrollando en mi nuevo trabajo he logrado incursionar en una nueva área de aprendizaje: Las expresiones regulares.

Aunque hace tiempo, cuando inicié el estudio del .Net Framework, me había topado ocasionalmente con las clases del System.Text.RegularExpressions, nunca había profundizado en su utilidad y en su gran potencial.

No fue hasta este proyeto en el que me vi en la necesidad de buscar una forma facil de encontrar el contenido de las etiquetas html de una página web, que me tope de frente con el hecho de que las funciones IndexOf y SubString no iban a representar una opción viable a corto plazo, para este propósito.

Luego de una búsqueda extensa en Internet encontré varios sitios que hablaban sobre la utilidad de las expresiones regulares para este propósito y comencé a investigar. Luego de varias lecturas comprendí dos cosas importantes:

- Utilizar las expresiones regulares era la mejor forma de resolver mi problema.

- No sabía nada acerca de ellas.

Obviamente el segundo problema era el primero a resolver, y como siempre, inicié mi búsqueda en el punto más lógico: la ayuda del .Net Framework. Sin embargo me tope con un problema: la ayuda describe con detalle como usar las clases para manejar las expresiones regulares, pero toca en forma muy superficial el tema de estas como un lenguaje.

Así que el siguiente paso lógico – una búsqueda en Internet – me llevó al siguiente sitio:

http://www.regular-expressions.info/tutorial.html

Este lugar llenó todas mis necesidades de aprendizaje y el resto fue experimentar con una de las versiones de prueba de los programas mencionados en el sitio (el EditPad Pro) el cual terminó de aclarar todas mis dudas en la práctica.

En las siguientes entregas de esta serie tratare de resumir en forma fácil de asimilar el conocimiento adquirido en esta investigación y algunas de las formas en las que lo he puesto en práctica.

Seguir

Get every new post delivered to your Inbox.