Expresiones Regulares en C#

1 - Qué es una expresión regular? 

Una expresión regular es una secuencia de caracteres que define un patrón de búsqueda sobre un texto.

Por lo tanto a esta secuencia de caracteres la denominamos patrón.

 

C# nos proporciona un motor o librería la cual permite comprobar expresiones regulares. Cuando utilizamos expresiones regulares dentro de C# lo hacemos utilizando el tipo Regex.

 

1.1 - Definir expresiones regulares

Patrón en expresiones regulares 

Cuando definimos expresiones regulares debemos entender que lo que estamos haciendo es buscar coincidencias de un patrón dentro de un texto, la cual es una cadena de caracteres dentro de un texto, ya sea en una variable string o en un fichero.

Este patrón se puede definir utilizando diferentes categorías, ya sean caracteres, operadores y constructores. He creado una Chuleta para crear expresiones regulares, en este enlace, la cual contiene todas las posibilidades.

Para este post utilizaremos la siguiente frase:

Frase numero 01 en el blog de netmentor.es para explicar las expresiones regulares, repeticion de caracteres y 01 numeros01

nota: la frase es un poco extraña para así tener variedad a la hora de comprobar los patrones. 

Unas de las más comúnes pueden ser las siguientes:

Búsqueda literal "numero 01" Frase numero 01 en el...
Inicio de frase "^Frase" Frase numero 01...
Condicional "numero [01]" Frase numero 01 en el...
Repeticiones "numero [01]{2}" Frase numero 01 en el...
Repeticiones 2 (0 -N veces) "numero [01]*" Frase numero 01 en el...
Rango "[b-o]{4}" ...en el blog de...
Espacios en blanco "\s" Frase numero 01 en el...
Cualquier número "\d*" Frase numero 01 en el...
Cualquier letra "\w*" Frase numero 01 en el...

 

Grupos en expresiones regulares

Creando patrones tenemos la posibilidad de crear grupos, para ello introduciremos parte del patrón entre paréntesis, comúnmente se utilizan para buscar y encontrar valores. 

En el ejemplo de la frase de este post podríamos crear un patrón como el siguiente “Frase numero (\d*)” el cual sería un resultado positivo del siguiente texto: “Frase numero 01” y el grupo sería únicamente 01.

 

2 - Expresiones regulares en C#

En C# vamos a utilizar el tipo Regex para crear expresiones regulares. Lo primero que tenemos que tener en cuenta es que para inicializarlo utilizaremos los métodos estáticos sobre las inicializaciones de variables, ya que dentro del método estático .Match por ejemplo (lo hace en todos), llama a la inicialización del tipo new Regex(), pero además incluye un sistema de caché, por lo que si hacemos dos Regex.Match(patrón) será más rápido que inicializar dos objetos. 

No olvidar que para escapar caracteres en C# lo hacemos con el carácter \ por lo que si queremos indicar el carácter \ para la expresión regular deberemos bien o poner el carácter @ antes de la frase o indicar dos contrabarras \\

 

2.1 - Clase Regex en C#

Cuando ejecutamos una comprobación en Regex dependiendo a qué método estemos invocando podemos tener diferentes tipos de respuesta. 

Tenemos los tipos simples como pueden ser string o bool, pero además disponemos de dos tipos de la librería RegularExpressions los cuales son 

Match que contiene las siguientes propiedades importantes: 

  • success: si el patrón existe en la frase.
  • Groups: Devuelve los Grupos
  • Index: Posición del texto donde se encuentra el el “match”
  • NextMatch(): Itera al siguiente elemento si existe.
  • MatchCollection que es una colección de tipos Mach lo que implica que si utilizamos LINQ  podemos iterar, o buscar.

 

Los métodos más comunes que vamos a utilizar dentro de la clase Regex son los siguientes: 

  • Regex.IsMatch(string frase, string patron) devuelve bool

El cual nos indica si el patrón proporcionado esta dentro de esa frase. hay que tener cuidado con este, ya que si el patrón está repetido múltiples veces sigue dando verdadero. 

bool resultIsMatch = Regex.IsMatch(frase, @"netmentor\.es");
//resultIsMatch es true

 

  • Regex.Match(string frase, string patron) devuelve Match
Match resultMatch = Regex.Match(frase, @"netmentor\.es");

 

  • Regex.Matches(string frase, string patron) devuelve MatchCollection
MatchCollection resultMatches = Regex.Matches(frase, "\\d");
foreach(Match match in resultMatches.ToList())
{
    var posicion = match.Index;
}

 

  • Regex.Replace(string frase, string patron, string reemplazo) devuelve la frase original actualizada con el reemplazo
string fraseCambiada = Regex.Replace(frase, "las expresiones regulares", "regex");
//el valor de nuestra frase original cambia a ".... para explicar regex, repeti..."

 

  • Regex.Split(string frase, string patron) devuelve un array string[] que contiene las diferentes partes del texto divididas por el patrón.
string[] arrayFrases = Regex.Split(frase, ",");
//array que contiene 2 string
//arrayFrases[0] ->Frase numero 01 en el blog de netmentor.es para explicar las expresiones regulares
//arrayFrases[1] ->  repeticion de caracteres y 01 numeros01.

Como he indicado, disponemos de más métodos, pero estos 5 van a cuplir el 99.9% de las veces que necesitemos comprobar cualquier elemento con expresiones regulares. 

 

2.2 - Opciones al invocar Regex en c#

Cuando estamos ejecutando expresiones regulares en c# tenemos disponible sobrecarga de métodos, en los que podemos incluir un parámetro adicional en el método. Este parámetro es RegexOptions Esto quiere decir que cuando ejecutemos la expresion regular, contendrá opciones adicionales o diferentes a los valores por defecto. 

Tenemos varias opciones, pero las más importantes son las siguientes: 

  • RegexOptions.IgnoreCase

Como sabemos las expresiones regulares distinguen entre mayúsculas y minúsculas, si habilitamos la opción IgnoreCase no las tendrá en cuenta.

Match resultMatchCase = Regex.Match(frase, @"NETMENTOR\.es", RegexOptions.IgnoreCase);

 

  • RegexOptions.Compiled

Nos permite compilar una expresión regular. Lo cual hace que se compile a binario durante la compilación, pero gana mucho rendimiento en tiempo de ejecución si la utilizamos mucho. para casos comunes de una vez de vez en cuando, no es necesario. 

Regex regexCompilada = new Regex(@"netmentor\.es", RegexOptions.Compiled );
Match resultMatchRight = regexCompilada.Match(frase);

 

Microsoft tiene un ejemplo  donde compara la misma expresión regular compilada e Interpretada sobre un fichero de texto.

Cuando comprueban un fichero con 10 líneas la versión Interpretada tarda 0.0047491ms milisegundos, mientras que la compilada 0.0141872 ms. unas 3 veces más. Mientras que si el fichero son 13 mil líneas la interpretada tarda 1.192ms y la compilada 0.7ms, que es algo más de la mitad. 

 

Conclusión

En el mundo laboral el mayor uso que solemos dar a las expresiones regulares es a la hora de hacer validaciones de campos que utiliza el usuario, por ejemplo para comprobar que el usuario no introduce caracteres en campos donde debería haber solo números, comprobar que el email es correcto. etc.