Aprende Regex, Expresiones regulares, con MVVM fácil

 Aprende Regex, Expresiones regulares, con MVVM fácil
Regex-NET

Hola! Vengo de hablaros de Regex. Nos viene a ser muy útil cuando necesitamos validar textos. Por ejemplo, la secuencia de caracteres y números que tiene que contener la contraseña, guardar variables con una "expresión"para luego poder extraerlo con más seguridad de no estar leyendo otra variable, etc... Para Regex, hay libros enteros, así que os voy a contar solo una pequeñísima parte. Lo primero, veremos un poco la base de Regex, crearemos una App para validar Regex y finalmente, lo que me gusta siempre os enseñare tools, atajos, etc... :D

("me dice un buen amigo: ¿tu que haces primero? aprender el programa o sus atajos? yo es que lo veo muy claro jeje")

¿que es regex?

Con regex podemos describir nuestros "patrones" de texto. Una vez que hayamos descrito el patrón correctamente, podemos utilizarlo para hacer búsquedas, reemplazos, extracción y modificación de texto. Regex, lo podemos encontrar en el siguiente namespace: using System.Text.RegularExpressions; Como ya hemos hablado antes, su función es crear algún patrón. Entonces vamos a crear el objecto Regex con un patrón que busque un texto de a-z con 10 de longitud por ejemplo:Regex obj = new Regex("[a-z]{10}"); Finalmente, para poder buscar con el siguiente patrón, lo haríamos con IsMatch: MessageBox.Show(obj.IsMatch("geeky theory").ToString());IsMatchnos devuelve un true/false dependiendo del patrón que tenemos y si ha podido encontrarlo o no en el texto Ahora vamos a explicar los 5 comandos de regex más importantes:

  • [] dentro irá el patrón que debe cumplir el texto. Es decir, los caracteres que deben de coincidir.
  • {} especifica el número de caracteres.
  • () para agrupar.
  • ^ marca el empezar del patrón. Por ejemplo con el patrón ^xyz, "xyz123" saldría true, mientras que "123xyz" no encaja con el patrón diseñado
  • $ marca el final del patrón. Por ejemplo con el patrón 123$, "xyz123" saldría true, mientras que "123xyz" no encaja con el patrón diseñado

El anterior ejemplo cuando creábamos el objecto regex, su expresión también lo podemos expresarlo de la siguiente forma: ^[a-z]{10}$

RegexTester

Ahora vamos a la parte de creación de una App muy muy sencilla para "validar" expresiones regex de un texto introducido. Lo primero, Abrimos Visual Studio. Nuevo proyecto y elegimos un proyecto WPF (Windows Presentation Foundation) con .NET 4.5. Luego creamos carpetas ViewModel, Base y View de la siguiente manera:

FoldersRegexTester

En la Carpeta "Base", como visto en los VideoTutoriales anteriores de MVVM, creamos la clases ViewModelBase ó VMMain (es lo mismo) y el DelegateCommand que implementa la interfaz ICommand. Una vez hecho esto, ya tenemos listo un entorno simple de MVVM para empezar a trabajar. Ahora en la Carpeta "ViewModel"creamos la clase MainViewModel, también visible en la foto. No olvidaros de hacer estas clases publicas para que podemos acceder a ellas. Entonces Vamos a nuestro MainWindow.xaml y establecemos en su DataContext en MainViewModel. Lo podemos hacer de las siguientes formas: En el XAML de MainWindow.xaml: <Window.DataContext> <vm:MainViewModel></vm:MainViewModel> </Window.DataContext> O en su Code Behind MainWindow.xaml.cs: public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.DataContext = new MainViewModel(); } } NOTA La asignación de nuestro ViewModel en el CodeBehind aunque funcione, no concuerda con la filosofía de MVVM. Debemos hacerlo o en el XAML o mejor por medio de un IoC (Contenedores tipo Autofac o Unity) Ahora ya podemos empezar a construir la App!! Vamos creando un XAML a nuestro gusto, yo por ejemplo lo he construido así: <Window x:Class="RegexTester.Views.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="clr-namespace:RegexTester.ViewModels" SizeToContent="WidthAndHeight" Title="MainWindow" MinHeight="150" MinWidth="400"> <Window.DataContext> <vm:MainViewModel></vm:MainViewModel> </Window.DataContext> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Label Style="{StaticResource CommonLabelStyle}">Regex</Label> <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding RegexPattern, UpdateSourceTrigger=PropertyChanged, Delay=500}" Style="{StaticResource CommonTextBoxStyle}"/> <Label Grid.Row="1" Grid.Column="0" Style="{StaticResource CommonLabelStyle}">Test</Label> <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding InputText, UpdateSourceTrigger=PropertyChanged, Delay=500}" Style="{StaticResource CommonTextBoxStyle}"/> <Label Grid.Row="2" Grid.Column="1" Content="{Binding Message}" Style="{StaticResource CommonLabelStyle}"/> </Grid> </Window>

RegexTester

Si os dais cuenta, cree un Style para Label y otro para TextBox, aplicándolo luego con la propiedad Style. No es necesario pero si aconsejable en proyectos grandes. Simplemente lo he definido en nuestro App.xaml como recurso para luego pueda utilizarlo en cualquier XAML creado en mi proyecto. Si queréis verlo mejor, tendréis disponible en Github el proyecto. También otro apunte es que en los Binding de los TextBoxa parte de definir el nombre, he definido lo siguiente: UpdateSourceTrigger=PropertyChanged, Delay=500Esto significa que cada vez que escriba una letra más, la propiedad que está enlazada a ese TexBox se refrescará. También le he puesto 500ms de retraso para que no sea instantáneo. Bueno una vez creado el XAML, podemos empezar a definir los nombres que queremos para enlazarlo en el ViewModel. Elegido los nombres en los campos Text y Content con la palabra Binding, pasamos a crear nuesto ViewModel que se llama MainViewModelAquí creamos nuestras Properties con el mismo nombre que en nuestros Bindings ya que nuestro MainViewModel pertenece al DataContext del MainWindow.xaml donde las variables con un {Binding ____ } empezaran a buscar jerárquicamente desde su control (TextBox o Label) hacía arriba, llegándose hasta el nivel de DataContext del MainWindow donde están todos nuestro properties definido en MainViewModel. Yo por ejemplo he definido las siguientes: private string regexPattern; private string inputText; private string message; public string RegexPattern { get { return regexPattern; } set { if (regexPattern != value) { regexPattern = value; OnPropertyChanged(); } } } public string InputText { get { return inputText; } set { if (inputText != value) { inputText = value; OnPropertyChanged(); } } } public string Message { get { return message; } set { if (message != value) { message = value; OnPropertyChanged(); } } } Ahora terminada la infraestructura, podemos a darle vida. Voy a ser poco MVVM y en verde crear una interfaz para dichas acciones que se tienen que llevar acabo, para así separar controles específicos de cada plataforma, lo meto en un mismo método dentro del MainViewModel. En este metido tendremos la creación de Regex, asignación de un patrón y comprobación si el texto que le hemos metido cumple con el siguiente patrón.private Regex regex; private void ValidateInputText() { // vemos si tenemos algo metido en TextBox para el patron if (regexPattern == String.Empty) { Message = "Regex is Empty"; return; } try { // Vemos si lo que esta escrito cumple con el formato. regex = new Regex(regexPattern); Message = String.Empty; } catch (ArgumentException error) { // Sino mostramos el error Message = error.Message; return; } if (InputText != null) // si tenemos texto... { // Vemos si el texto introducido cumple con el patrón bool isMatch = regex.IsMatch(InputText); if (isMatch) { Message = "It's works!"; } else { Message = "No working :("; } } }Una vez que tenemos el método declarado, lo llamamos desde el Setter de las propiedades de RegexPattern y InputText:public string RegexPattern { get { return regexPattern; } set { if (regexPattern != value) { regexPattern = value; ValidateInputText(); OnPropertyChanged(); } } } public string InputText { get { return inputText; } set { if (inputText != value) { inputText = value; ValidateInputText(); OnPropertyChanged(); } } }Y ya esta! si le dais a ejecutar debería funcionar! o no? averiguarlo vosotros :D Con esto hemos repasado un poco el MVVM y hemos trabajado un poco con Regex. Pero claro para hacer un verdadero RegexTester... nos llevar un tiempecito aunque este no funciona nada mal, le queda camino a nuestro jogurín. Para eso existe una extensión para Visual Studio, que lo hacer de maravilla!

Y finalmente tienes aquí el enlace para Github

Octocat

Hasta la próxima geeks!