Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo se tratan tres operaciones de cadena: la coincidencia de patrones de expresión regular con System.Text.RegularExpressions.Regex, la búsqueda sin asignación en ReadOnlySpan<T>y la elección de un StringComparison valor para comparaciones correctas y rápidas.
Búsqueda de texto específico mediante expresiones regulares
La System.Text.RegularExpressions.Regex clase busca cadenas para patrones en lugar de subcadenas fijas. El método estático Regex.IsMatch toma la cadena de entrada, un patrón y marcas opcionales RegexOptions .
En el ejemplo siguiente se busca en cada frase la palabra osu sin distinción entre mayúsculas y minúsculas. El patrón the(ir)?\s coincide the opcionalmente seguido de ir, a continuación, un carácter de espacio en blanco:
| Pattern | Meaning |
|---|---|
the |
coincidir con el texto literal the |
(ir)? |
coincide con 0 o 1 repetición de ir |
\s |
coincidir con un carácter de espacio en blanco |
string[] sentences =
[
"Put the water over there.",
"They're quite thirsty.",
"Their water bottles broke."
];
string pattern = @"the(ir)?\s";
foreach (string s in sentences)
{
Console.Write($"{s,28}");
if (Regex.IsMatch(s, pattern, RegexOptions.IgnoreCase))
{
Console.WriteLine($" (match for '{pattern}' found)");
}
else
{
Console.WriteLine();
}
}
Validación de cadenas con un patrón
Para comprobar si una entrada completa coincide con una forma, delimite el patrón con ^ y $. En el ejemplo siguiente se valida que cada cadena es un número de teléfono de estilo ESTADOUNIDENSE: tres dígitos, tres dígitos, cuatro dígitos, separados por guiones:
| Pattern | Meaning |
|---|---|
^ |
coincide con el principio de la cadena |
\d{3} |
coincidir exactamente con tres caracteres de dígito |
- |
coincidir con un carácter literal - |
\d{4} |
coincidir exactamente con cuatro caracteres de dígito |
$ |
coincidir con el final de la cadena |
string[] numbers =
[
"123-555-0190",
"444-234-22450",
"690-555-0178",
"146-893-232",
"146-555-0122",
"4007-555-0111",
"407-555-0111",
"407-2-5555",
"407-555-8974",
"407-2ab-5555",
"690-555-8148",
"146-893-232-"
];
string pattern = """^\d{3}-\d{3}-\d{4}$""";
foreach (string s in numbers)
{
Console.Write($"{s,14}");
Console.WriteLine(Regex.IsMatch(s, pattern) ? " - valid" : " - invalid");
}
Para obtener la sintaxis de patrón completa, consulte Lenguaje de expresiones regulares: referencia rápida.
Elección entre string métodos y expresiones regulares
string métodos y Regex resolver problemas superpuestos. Prefiere string métodos cuando el texto que está buscando es un valor literal, un prefijo o sufijo conocido, o un delimitador fijo. Son más fáciles de leer y más rápido, ya que no pagan el costo de compilar y ejecutar un patrón. Alcance para Regex cuando el destino de búsqueda sea una forma, como alternancias, grupos opcionales, clases de caracteres repetidos o validación anclada. Como regla general, si puede escribir la búsqueda como una o dos string.Contains / / StartsWithIndexOf llamadas, hágalo.
Búsqueda mediante ReadOnlySpan<char>
Al analizar entradas grandes o ejecutar una búsqueda en una ruta de acceso activa, las asignaciones por llamada de string.Substring y string.Split pueden dominar.
ReadOnlySpan<char> proporciona una vista sobre una cadena existente (o matriz o búfer de pila) sin copiar y MemoryExtensions proporciona equivalentes basados en intervalos de los métodos comunes string , incluidos IndexOf:
ReadOnlySpan<char> input = "key1=alpha;key2=beta;key3=gamma".AsSpan();
ReadOnlySpan<char> needle = "key2=".AsSpan();
int start = input.IndexOf(needle);
if (start >= 0)
{
ReadOnlySpan<char> rest = input[(start + needle.Length)..];
int end = rest.IndexOf(';');
ReadOnlySpan<char> value = end >= 0 ? rest[..end] : rest;
Console.WriteLine($"key2 = {value}");
}
// => key2 = beta
La búsqueda basada en intervalos evita asignaciones porque los segmentos (input[start..], rest[..end]) son simplemente ventanas sobre los caracteres originales. El mismo enfoque se escala para analizar listas de clave-valor, encabezados y otro texto delimitado sin llamar nunca a Substring.
Consideraciones de rendimiento para StringComparison
La mayoría string de los métodos de instancia tienen sobrecargas que aceptan un StringComparison valor. Métodos como String.Equals(String) el valor predeterminado de ordinal, pero String.Compare(String, String) y String.IndexOf(String) el valor predeterminado para la referencia cultural actual. Esta diferencia es importante de dos maneras:
- Velocidad. La comparación ordinal es una prueba byte-for-byte que se ejecuta en bucles vectorizados ajustados. La comparación con reconocimiento cultural consulta una tabla de ordenación, recorre la combinación de caracteres y aplica reglas específicas de la configuración regional. Para la misma entrada, puede ser un orden de magnitud más lento.
- Exactitud. La comparación con reconocimiento cultural puede plegar caracteres que no se esperan (turco
i/I, alemánßass, ligaduras). Este comportamiento es adecuado para ordenar los nombres que ve un usuario, pero no es correcto para analizar identificadores, rutas de acceso o tokens de protocolo.
Para texto definido por la máquina, como nombres de archivo, direcciones URL, encabezados HTTP, identificadores y claves de configuración, pase StringComparison.Ordinal o StringComparison.OrdinalIgnoreCase explícitamente. Reserve valores compatibles con la referencia cultural para el texto en lenguaje natural que se muestra a los usuarios. Para obtener instrucciones completas, consulte procedimientos Best para comparar cadenas en .NET.