C#:eliminar caracteres no alfanuméricos de una cadena

C#:eliminar caracteres no alfanuméricos de una cadena

La forma más sencilla de eliminar caracteres no alfanuméricos de una cadena es usar expresiones regulares:

if (string.IsNullOrEmpty(s))
	return s;

return Regex.Replace(s, "[^a-zA-Z0-9]", "");
Code language: C# (cs)

Nota:no pases un nulo, de lo contrario obtendrás una excepción.

Regex es el enfoque más simple para resolver este problema, pero también es el más lento. Si le preocupa el rendimiento, consulte la sección de rendimiento a continuación.

Este ejemplo solo mantiene caracteres alfanuméricos ASCII. Si está trabajando con otros alfabetos, consulte la sección a continuación sobre cómo especificar caracteres que no sean ASCII.

Para un mejor rendimiento, use un bucle

Recorrer la cadena y tomar los caracteres que desea es 7,5 veces más rápido que las expresiones regulares (y 3 veces más rápido que usar Linq).

if (string.IsNullOrEmpty(s))
	return s;

StringBuilder sb = new StringBuilder();
foreach(var c in s)
{
	if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'))
		sb.Append(c);
}
return sb.ToString();
Code language: C# (cs)

No se moleste en usar expresiones regulares compiladas

El uso de expresiones regulares compiladas no ayuda mucho con el rendimiento en este escenario. En el mejor de los casos, es un poco más rápido. En el peor de los casos, es lo mismo que no usar expresiones regulares compiladas. Es más sencillo usar los métodos estáticos de expresiones regulares (como Regex.Replace()), en lugar de tratar de asegurarse de que el objeto de expresiones regulares compilado esté disponible en todas partes. En otras palabras, solo use los métodos de expresión regular estática en lugar de la expresión regular compilada.

Aquí hay un ejemplo del uso de expresiones regulares compiladas:

private static readonly Regex regex = new Regex("[^a-zA-Z0-9]", RegexOptions.Compiled);

public static string RemoveNonAlphanumericChars(string s)
{
	if (string.IsNullOrEmpty(s))
		return s;

	return regex.Replace(s, "");

}
Code language: C# (cs)

Use char.IsLetterOrDigit() si quiere todos los caracteres alfanuméricos Unicode

Tenga en cuenta que char.IsLetterOrDigit() devuelve verdadero para todos los caracteres alfanuméricos Unicode. Por lo general, cuando eliminas personajes, es porque sabes exactamente qué personajes quieres tomar. El uso de char.IsLetterOrDigit() solo debe usarse si desea aceptar TODOS los caracteres alfanuméricos Unicode y eliminar todo lo demás. Eso debería ser raro.

Es mejor especificar exactamente qué caracteres desea conservar (y luego, si usa expresiones regulares, aplique el operador ^ para eliminar todo excepto esos caracteres).

Resultados de referencia

Evalué cuatro enfoques para eliminar caracteres no alfanuméricos de una cadena. Pasé a cada método una cadena con 100 caracteres. El siguiente gráfico muestra los resultados:

Aquí están todas las estadísticas de referencia:

|        Method |       Mean |    StdDev |        Min |        Max |
|-------------- |-----------:|----------:|-----------:|-----------:|
|         Regex | 5,016.4 ns | 139.89 ns | 4,749.4 ns | 5,325.5 ns |
| RegexCompiled | 4,457.9 ns | 301.40 ns | 3,930.5 ns | 5,360.4 ns |
|          Linq | 1,506.9 ns |  76.75 ns | 1,393.0 ns | 1,722.3 ns |
|          Loop |   663.7 ns |  31.15 ns |   599.6 ns |   742.3 ns |Code language: plaintext (plaintext)

Especificación de caracteres no ASCII en expresiones regulares

¿Qué tal si necesita tratar con caracteres alfanuméricos que no son ASCII, como los siguientes caracteres griegos:

ΕλληνικάCode language: plaintext (plaintext)

Si está tratando con un alfabeto que no es ASCII, como el griego, puede buscar el rango Unicode y usar los puntos o caracteres del código.

Nota:Recuerde que se trata de eliminar caracteres. Entonces, con expresiones regulares, especifica qué caracteres desea y luego usa el operador ^ para hacer coincidir todo menos esos caracteres.

Usar puntos de código Unicode

Aquí hay un ejemplo de cómo especificar el rango de punto de código Unicode griego:

Regex.Replace(s, "[^\u0370-\u03FF]", "");
Code language: C# (cs)

Usar bloque con nombre Unicode

Para una mejor legibilidad, puede usar un bloque con nombre Unicode, como "IsGreek". Para especificar que desea usar un bloque con nombre, use \p{} así:

Regex.Replace(s, @"[^\p{IsGreek}]", "");
Code language: C# (cs)

Especifique exactamente qué caracteres Unicode desea

Puede especificar exactamente qué caracteres Unicode desea (incluido un rango de ellos):

Regex.Replace(s, "[^α-ωάΕ]", "");
Code language: C# (cs)

Esto es más fácil de leer que usar puntos de código.