Aparte de para las labores habituales de todo desarrollador (o sea, escribir c贸digo, jeje), Visual Studio es tambi茅n una estupenda herramienta para procesar archivos, sobre todo cuando necesitas hacer cambios masivos en contenidos mediante buscar y reemplazar. Como te permite abrir muchos archivos y luego buscar cadenas sobre ellos usando expresiones regulares, puedes hacer cambios m谩s o menos complejos con relativa facilidad.

Sin embargo la sintaxis de expresiones regulares que admite difiere en bastantes cosas de la sintaxis habitual en la mayor铆a de los lenguajes de programaci贸n, como C#/.NET o JavaScript, por ejemplo.

Para expresiones regulares b谩sicas es igual y no tendr谩s problemas, pero hay otras cuestiones que, de entrada, resultar谩n m谩s complejas porque cambia la sintaxis.

Por ejemplo, imagina que tienes que cambiar todas las etiquetas <ul>  dentro de varios archivos HTML por etiquetas <ol>, para convertir todas las listas en listas ordenadas.

Abrir铆as el di谩logo de buscar y reemplazar (CTRL+H) y podr铆as probar con esta configuraci贸n:

BuscarExpReg_1

La expresi贸n regular (\<ul.*\>) no tiene nada raro aparentemente: busca las cadenas que empiecen por <ul y contengan (o no) lo que sea dentro de la etiqueta, cerr谩ndose, claro est谩, con un 鈥>鈥.

Si tenemos algo como esto:

BuscarExpReg_2

Encontrar谩 sin problema el <ul> que tenemos.

Sin embargo consideremos este otro c贸digo:

BuscarExpReg_3

Alg煤n dise帽ador HTML desbocado nos ha puesto en la misma l铆nea toda la l铆nea. Si ahora hacemos uso del di谩logo anterior para hacer la b煤squeda, el primer <ul> aparecer谩 sin problemas como antes, pero esto es lo que encontrar谩 la expresi贸n para el segundo:

BuscarExpReg_4

Efectivamente: la l铆nea entera.

El problema es que por defecto, como en casi todos los lenguajes, las expresiones regulares son 鈥渃odiciosas鈥 (o en ingl茅s 鈥済reedy鈥). Por ello tratan de que se cumpla la expresi贸n pero de la manera m谩s amplia posible. Es decir, si le ponemos 鈥.*\>鈥 tratar谩 de buscar cualquier cadena de cualquier longitud (el punto con el asterisco) que termine con un 鈥>鈥. Como es 鈥渃odiciosa鈥 por defecto, buscar谩 la m谩s larga posible. En una l铆nea como la resaltada en la figura anterior (por defecto no son multi-l铆nea) la expresi贸n se extiende hasta alcanzar el 煤ltimo 鈥>鈥 de la misma. Pero eso no es lo que nosotros queremos.

Para evitar este problema en una expresi贸n regular com煤n en C# o JavaScript usamos el operador 鈥?鈥. Este operador a continuaci贸n de un modificador de longitud estilo 鈥*鈥 o 鈥+鈥 indica que 茅ste debe comportarse de la manera menos codiciosa posible (non-greedy). Si intentamos meter este operador en el di谩logo de Visual Studio veremos que, directamente, no encuentra nada.

El motivo es que las expresiones regulares de VS consideran este operador 鈥?鈥 como  una interrogaci贸n m谩s, es decir, ser铆a como decirle que la cadena debe terminar con una interrogaci贸n y un mayor.

Entonces 驴c贸mo se consiguen expresiones non-greedy en Visual Studio?

Pues muy sencillo. Simplemente hay que utilizar la sintaxis especial que le han otorgado (la verdad es que deber铆an haber usado una sintaxis com煤n, la misma que en 鈥揘ET para evitar problemas, pero sus buenas razones tendr铆an quiero pensar).

De hecho precisamente por esta sintaxis especial es necesario marcar los s铆mbolos 鈥>鈥 y 鈥<鈥 como 鈥淺>鈥 y 鈥淺<鈥, es decir, con caracteres de escape, porque de otro modo 茅stos indican el fin y el principio de l铆nea respectivamente (en condiciones normales no habr铆a que 鈥渆scapearlos鈥).

Si vemos con detenimiento la tabla de caracteres de control especiales para estas expresiones regulares nos daremos cuenta de que Visual Studio utiliza dos caracteres especiales propios para indicar coincidencias no-codiciosas:

路 @: es equivalente a 鈥*?鈥 en expresiones regulares convencionales. Es decir, coincide con cualquier n煤mero de caracteres de manera no codiciosa, incluyendo el hecho de que no haya ninguno (o sea, puede haberlos o no).

路 #: es equivalente a 鈥+?鈥 en expresiones regulares convencionales. Es decir, coincide con cualquier n煤mero de caracteres excepto 0 de manera no codiciosa. Es decir, que debe haber al menos una coincidencia.

As铆, en el caso anterior, podr铆amos usar este di谩logo para encontrar correctamente los <ul> de nuestras p谩ginas:

BuscarExpReg_5

Es decir, la expresi贸n regular se descompone en los siguientes elementos:

路 鈥淺<ul鈥: la cadena debe empezar por 鈥<ul鈥

路 鈥[email protected]: cualquier caracter, el n煤mero de veces que sea, incluyendo el hecho de que no exista ninguno. As铆 encaja con <ul> y tambi茅n con <ul class=鈥滾ista鈥> o con cualquier otro atributo que tenga la etiqueta. El caracter @ indica que debe ser non-greedy, es decir, que debe detectar la cadena m谩s corta posible.

路 鈥淺>鈥: la cadena debe terminar con un 鈥>鈥, como todas las etiquetas HTML.

F谩cil, pero cuando intentas usar expresiones regulares normales puedes volverte loco麓. As铆 que ya sabes, ten a mano siempre el enlace anterior y verifica los caracteres especiales que usa Visual Studio para sus b煤squedas.

El objetivo de este post era llamar la atenci贸n sobre esta sintaxis especial, ayudar a alguno que tuviera problemas con el uso de esta herramienta y, de paso, repasar los m铆nimos de las expresiones regulares, algo que todo programador deber铆a conocer al dedillo trabaje en el lenguaje que trabaje :-)

隆Espero que te sea 煤til!

💪🏻 驴Este post te ha ayudado?, 驴has aprendido algo nuevo?
Pues NO te pido que me invites a un caf茅... Te pido algo m谩s f谩cil y mucho mejor