csharp-regular-expressions-regex

Qué son y cómo usar Expresiones Regulares (Regex) en C#

  • 4 min

Una expresión regular es una secuencia de caracteres que forma un patrón de búsqueda. Este patrón puede ser utilizado para encontrar cadenas de texto que coincidan con ese patrón o para reemplazar texto dentro de una cadena.

Imaginad que tenéis que buscar en un texto “cualquier fecha que tenga formato DD/MM/AAAA”. Podríais hacer un bucle for con 20 if/else comprobando si hay números y barras… o podríais usar una sola línea de Regex.

En C#, las expresiones regulares se manejan mediante la clase Regex, que está incluida en el espacio de nombres System.Text.RegularExpressions.

Sintaxis básica

Antes de ir al código C#, necesitamos entender el lenguaje de los patrones. Al principio parece que alguien ha aporreado el teclado, pero tiene lógica (más o menos).

SímboloSignificadoEjemploCoincide con
.Cualquier carácter (menos salto de línea)a.o”aro”, “a1o”, “a-o”
\dUn dígito (0-9)\d\d”05”, “99”
\wAlfanumérico (letras, números, _)\w+”Usuario1”, “Hola”
^Inicio de la línea (Ancla)^HolaEmpieza por “Hola”
$Fin de la línea (Ancla)fin$Acaba en “fin”
*0 o más vecesa*"", “a”, “aaa”
+1 o más vecesa+”a”, “aaa” (pero no "")
?0 o 1 vez (Opcional)colou?r”color”, “colour”
[]Rango o conjunto[A-Z]Cualquier mayúscula

La clase Regex

En C#, la clase par regular expressions es Regex. Tenemos dos formas de usarla:

  1. Métodos Estáticos: Para usos rápidos y únicos (Regex.IsMatch(...)).
  2. Instancia: Para reutilizar el mismo patrón muchas veces (new Regex(...)).

Validación (IsMatch)

El uso más común: ¿El texto cumple el patrón? (ej: validar un email, un DNI, un teléfono).

using System.Text.RegularExpressions;

string input = "1234A";
// Patrón: 4 dígitos seguidos de una letra mayúscula
string patron = @"^\d{4}[A-Z]$"; 

bool esValido = Regex.IsMatch(input, patron);

Console.WriteLine(esValido); // True

Copied!

Fijaos en la @ antes del string del patrón (@"..."). Esto es un Verbatim String. Es casi obligatorio en Regex para no tener que escapar cada barra invertida (\) dos veces.

Extracción de datos (Match y Groups)

Aquí es donde Regex tiene mayor utilidad. No solo validamos, sino que sacamos información del texto.

Imaginad que tenemos un log: "Error en el sistema: [Código 500] - Timeout". Queremos sacar el número de error.

string texto = "Error en el sistema: [Código 500] - Timeout";
string patron = @"\[Código (\d+)\]"; // Los paréntesis () crean un GRUPO

Match coincidencia = Regex.Match(texto, patron);

if (coincidencia.Success)
{
    // Group[0] es toda la coincidencia: "[Código 500]"
    // Group[1] es lo de dentro del paréntesis: "500"
    string codigo = coincidencia.Groups[1].Value;
    Console.WriteLine($"El error es: {codigo}");
}

Copied!

Búsqueda múltiple (Matches)

Si esperamos encontrar el patrón varias veces en el mismo texto (ej: buscar todos los emails en un documento).

string texto = "Contacta con [email protected] o con [email protected]";
string patron = @"\w+@\w+\.com";

MatchCollection resultados = Regex.Matches(texto, patron);

foreach (Match m in resultados)
{
    Console.WriteLine($"Email encontrado: {m.Value}");
}

Copied!

Reemplazo y limpieza (Replace)

Podemos usar Regex para hacer un “Buscar y Reemplazar” inteligente.

string telefonoSucio = "(+34) 666-55-44";
// Queremos dejar solo los números. 
// \D significa "Todo lo que NO sea un dígito"
string soloNumeros = Regex.Replace(telefonoSucio, @"\D", ""); 

Console.WriteLine(soloNumeros); // "346665544"

Copied!

También podemos usarlo para ocultar datos sensibles:

string tarjeta = "1234-5678-9012-3456";
// Reemplaza los primeros 12 dígitos por X
string oculta = Regex.Replace(tarjeta, @"^\d{4}-\d{4}-\d{4}", "XXXX-XXXX-XXXX");

Copied!

Rendimiento y optimización

Regex es potente, pero lento si se usa mal. El motor de Regex tiene que compilar el patrón a un código interno antes de ejecutarlo.

Si tenéis un patrón complejo que vais a usar millones de veces dentro de un bucle, podéis compilarlo con RegexOptions.Compiled.

// Tarda más en crearse (new), pero es más rápido al ejecutarse (IsMatch)
Regex regexCompilada = new Regex(@"^\d+$", RegexOptions.Compiled);

Copied!

No uséis Compiled para todo. La compilación consume CPU y memoria inicial. Usadlo solo para expresiones estáticas muy reutilizadas.