Posts Tagged ‘regex’

Regex replace

April 6th, 2009

Ya e hablado aquí y aquí sobre las expresiones regulares, pero nunca se tenie demasiadas de ellas.

Trabajando con un pequeño proyecto personal requería buscar dentro de un texto ocurrencias como @Nombre y #Nombre y convertirlas en un link, la solución es obvia y sencilla con expresiones regulares:

Regex.Replace("this is an example @AlbertEin", 
                    "(?<type>[@#])(?<nick>\\w{1,}[^ ])", 
                    "<a href=\"http://twitter.com/${nick}\">${type}${nick}</a>");

Esto remplaza “this is an example @AlbertEin” por “this is an example @AlbertEin“.

La expresión regular:

(?<type>[@#])(?<nick>\\w{1,}[^ ])

significa: captura bajo el nombre “type” la ocurrencia de texto que inicie con @ ó #, despues captura bajo el nombre “nick” el texto que siga que contenga al menos un carácter de texto hasta que te encuentres con un espacio en blanco.

Espero que después de tres advertencias ahora si vayan y aprendan de esta útil herramienta para la manipulación de texto.

Aprendiendo Regex – El imperio contrataca.

February 21st, 2008

Gnoblis posteo hacerca de un pequeño programa que hizo para convertir bbcode a html en su web: http://gnoblis.gamersla.net/?p=67. El codigo esta aca http://gamersla.net/gnoblis/descargas/CCast.cs

Su solucion si bien funciona, no es de lo mas elegante. El problema es facilmente resuelto con expresiones regulares, y se lo hizo saber en un comentario en su post.

Claro, los que me conocen sabran que no es suficiente haberle dicho como se podria resolver mejor, ¡hace falta hacerlo uno mismo!

Asi que como demostracion del poder de las expresiones regulares y que no soy un hablador les muestro el codigo:

Nota, el programa no lo probe a excepcion de las expreciones regulares, por lo que pueden encontrarse con sorpresas ;)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
 
class Program
{
 
    public static void Main(string[] args)
    {
 
        StreamReader inputReader;
        StreamWriter outputWriter;
        string actualLine;
        StringBuilder inputFileContent = new StringBuilder ();
 
        foreach (string actualFile in args) //Agrego la capacidad de convertir varios archivos a la ves
        {
            if (!File.Exists(actualFile))
            {
                Console.WriteLine("File not found, skipped: {0}", actualFile);
                continue;                   //Ignoramos el archivo, pero seguimos con los demas \o/
            }
 
            inputReader = new StreamReader(File.OpenRead(actualFile));
 
 
            inputFileContent.Remove(0, inputFileContent.Length);
            while ((actualLine = inputReader.ReadLine()) != null)
                inputFileContent.AppendLine(string.Format("{0}{1}", actualLine, "<br />"));
 
            inputReader.Close ();
 
            if (inputFileContent.Length == 0)
            {
                Console.WriteLine("Empty file, skipped: {0}", actualFile);
                continue;
            }
 
            string bbcodeData = inputFileContent.ToString();
 
            //Quitamos todos los espacios antes y despues de un igual, no solo uno
            bbcodeData = Regex.Replace(bbcodeData, @"\ {0,}=\ {0,}", "=", RegexOptions.IgnoreCase | 
                                                                          RegexOptions.Multiline);
 
            //Convertimos [b], [i], [u], [s] y sus respectivos cierres
            bbcodeData = Regex.Replace(bbcodeData, @"\[(?<tag>\/{0,1}[b|i|u|s])\]", @"<${tag}>", 
                RegexOptions.IgnoreCase | RegexOptions.Multiline);
 
            //imagenes
            bbcodeData = Regex.Replace(bbcodeData, @"\[img\](?<url>.*?)\[\/img\]",
                "<img src=\"${url}\" />", RegexOptions.IgnoreCase | RegexOptions.Multiline);
 
            //Links
            bbcodeData = Regex.Replace(bbcodeData, @"\[url=(?<url>.*?)\](?<data>.*?)\[/url\]",
                "<a href=\"${url}\">${data}</a>", RegexOptions.IgnoreCase | RegexOptions.Multiline);
 
            //Colores
            bbcodeData = Regex.Replace(bbcodeData, @"\[color=(?<color>.*?)\](?<data>.*?)\[/color\]", 
                "<font color=\"${color}\">${data}</font>", RegexOptions.IgnoreCase | 
                                                           RegexOptions.Multiline);
 
            outputWriter = new StreamWriter (File.Create(actualFile + ".html"));
 
            outputWriter.Write(bbcodeData);
 
            outputWriter.Close();
        }
    }
}

¿No sabes Regex? ¡Aprende!

December 7th, 2007

Algo de lo que me e dado cuenta cuando e dado platicas/talleres/cursos es que la gran mayoría de los desarrolladores, al menos de la región, no tienen ni puta idea acerca de que demonios son las expresiones regulares (Regex para los amigos).

Muchos recuerdan haber escuchado algo al respecto en su clase de autómatas en la universidad, pero como a todos, les paso de noche :P .

Es difícil de entender como la gente puede pasarse sentado en su vida profesional sin saber Regex, escribiendo cientos de lineas de código resolviendo problemas que con unos cuantos caracteres de Regex queda solucionado.

Si aun no sabes Regex, ¡deja de leer esto inmediatamente y ponte a buscar información al respecto!

Para los escépticos, un pequeño ejemplo:

Imagina que quieres validar que un teléfono siga el formato (900) 9-00-00-00, la forma común de hacerlo seria algo cómo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    bool isValidPhoneNumber(string input)
    {
        //Validate (900) 9-00-00-00
        if (input.Length != 16)
            return false;
        if (!input.StartsWith("("))
            return false;
        if (input[4] != ')')
            return false;
        int number;
        if (!int.TryParse(input.Substring(1, 3), out number))
            return false;
        if (input[1] == '0' || !char.IsNumber(input[1]))
            return false;
        if (input[5] != ' ')
            return false;
        string[] numbers = input.Substring(6, 10).Split ('-');
        if (numbers.Length != 4)
            return false;
        foreach (string subpart in numbers)
            if (!int.TryParse(subpart, out number))
                return false;
        if (numbers[0][0] == '0')
            return false;
        return true;
    }

Es tedioso de hacer, resulta fácil dejar errores en el, sin mencionar que es completamente horrible y resulta difícil de entender, y precisamente este es uno de los momentos en que Regex es útil:

1
2
3
4
5
6
7
8
   bool isValidPhoneNumber(string input)
    {
        //Validate (900) 9-00-00-00
        string expression = @"^\([1-9]\d{2}\)\ [1-9](\-\d{2}){3}$";
        System.Text.RegularExpressions.Regex regex = 
            new System.Text.RegularExpressions.Regex(expression);
        return regex.IsMatch(input);
    }

Si bien la sintaxis puede resultar confusa al inicio, basta un poco de practica para acostumbrarse a ella y puede llegar a ahorrarte toneladas de trabajo, especialmente si la usas para buscar patrones de texto en ves de solamente validación.

Confíen en mi, si no las conocen, ¡Aprendan!.

P.S: No me hago responsable de cualquier mal uso que puedan hacer de ellas ;)