remove ltrim last ejemplos c# removing-whitespace

ltrim - trim c#



¿Una forma eficiente de eliminar TODOS los espacios en blanco de String? (16)

Aquí hay otra variante:

public static string RemoveAllWhitespace(string aString) { return String.Join(String.Empty, aString.Where(aChar => aChar !Char.IsWhiteSpace(aChar))); }

Como con la mayoría de las otras soluciones, no he realizado pruebas exhaustivas de referencia, pero esto funciona lo suficientemente bien para mis propósitos.

Estoy llamando a una API REST y estoy recibiendo una respuesta XML. Devuelve una lista de los nombres de un área de trabajo y estoy escribiendo un IsExistingWorkspace() rápido de IsExistingWorkspace() . Dado que todos los espacios de trabajo constan de caracteres contiguos sin espacios en blanco, supongo que la forma más sencilla de averiguar si un espacio de trabajo en particular está en la lista es eliminar todos los espacios en blanco (incluidas las nuevas líneas) y hacer esto (XML es la cadena recibida de la web solicitud):

XML.Contains("<name>" + workspaceName + "</name>");

Sé que distingue entre mayúsculas y minúsculas, y confío en eso. Solo necesito una manera de eliminar todos los espacios en blanco en una cadena de manera eficiente. Sé que RegEx y LINQ pueden hacerlo, pero estoy abierto a otras ideas. Estoy mayormente preocupado por la velocidad.


Aquí hay una alternativa lineal simple a la solución RegEx. No estoy seguro de cuál es más rápido; Tendrías que compararlo.

static string RemoveWhitespace(string input) { StringBuilder output = new StringBuilder(input.Length); for (int index = 0; index < input.Length; index++) { if (!Char.IsWhiteSpace(input, index)) { output.Append(input[index]); } } return output.ToString(); }


Asumo que su respuesta XML se ve así:

var xml = @"<names> <name> foo </name> <name> bar </name> </names>";

La mejor manera de procesar XML es usar un analizador XML, como LINQ to XML :

var doc = XDocument.Parse(xml); var containsFoo = doc.Root .Elements("name") .Any(e => ((string)e).Trim() == "foo");


Encontré un buen artículo sobre este tema en CodeProject por Felipe Machado (con la ayuda de Richard Robertson )

Probó diez métodos diferentes. Esta es la versión insegura más rápida ...

public static unsafe string TrimAllWithStringInplace(string str) { fixed (char* pfixed = str) { char* dst = pfixed; for (char* p = pfixed; *p != 0; p++) switch (*p) { case ''/u0020'': case ''/u00A0'': case ''/u1680'': case ''/u2000'': case ''/u2001'': case ''/u2002'': case ''/u2003'': case ''/u2004'': case ''/u2005'': case ''/u2006'': case ''/u2007'': case ''/u2008'': case ''/u2009'': case ''/u200A'': case ''/u202F'': case ''/u205F'': case ''/u3000'': case ''/u2028'': case ''/u2029'': case ''/u0009'': case ''/u000A'': case ''/u000B'': case ''/u000C'': case ''/u000D'': case ''/u0085'': continue; default: *dst++ = *p; break; } return new string(pfixed, 0, (int)(dst - pfixed)); }

Y la versión segura más rápida ...

public static string TrimAllWithInplaceCharArray(string str) { var len = str.Length; var src = str.ToCharArray(); int dstIdx = 0; for (int i = 0; i < len; i++) { var ch = src[i]; switch (ch) { case ''/u0020'': case ''/u00A0'': case ''/u1680'': case ''/u2000'': case ''/u2001'': case ''/u2002'': case ''/u2003'': case ''/u2004'': case ''/u2005'': case ''/u2006'': case ''/u2007'': case ''/u2008'': case ''/u2009'': case ''/u200A'': case ''/u202F'': case ''/u205F'': case ''/u3000'': case ''/u2028'': case ''/u2029'': case ''/u0009'': case ''/u000A'': case ''/u000B'': case ''/u000C'': case ''/u000D'': case ''/u0085'': continue; default: src[dstIdx++] = ch; break; } } return new string(src, 0, dstIdx); }

También hay algunos buenos puntos de referencia independientes en de Stian Standahl que también muestran cómo la función de Felipe es aproximadamente un 300% más rápida que la siguiente función más rápida.


Esta es la forma más rápida que conozco, aunque dijiste que no querías usar expresiones regulares:

Regex.Replace(XML, @"/s+", "")


He encontrado resultados diferentes para ser verdad. Estoy tratando de reemplazar todos los espacios en blanco con un solo espacio y la expresión regular fue extremadamente lenta.

return( Regex::Replace( text, L"/s+", L" " ) );

Lo que funcionó mejor para mí (en C ++ cli) fue:

String^ ReduceWhitespace( String^ text ) { String^ newText; bool inWhitespace = false; Int32 posStart = 0; Int32 pos = 0; for( pos = 0; pos < text->Length; ++pos ) { wchar_t cc = text[pos]; if( Char::IsWhiteSpace( cc ) ) { if( !inWhitespace ) { if( pos > posStart ) newText += text->Substring( posStart, pos - posStart ); inWhitespace = true; newText += L'' ''; } posStart = pos + 1; } else { if( inWhitespace ) { inWhitespace = false; posStart = pos; } } } if( pos > posStart ) newText += text->Substring( posStart, pos - posStart ); return( newText ); }

Primero intenté la rutina anterior reemplazando cada carácter por separado, pero tuve que cambiar a hacer subcadenas para las secciones sin espacio. Cuando se aplica a una cadena de 1,200,000 caracteres:

  • La rutina anterior lo hace en 25 segundos.
  • la rutina anterior + reemplazo de caracteres por separado en 95 segundos
  • La expresión regular abortó después de 15 minutos.

Mi solución es usar Split and Join y es sorprendentemente rápido, de hecho, es la más rápida de las respuestas principales aquí.

str = string.Join("", str.Split(default(string[]), StringSplitOptions.RemoveEmptyEntries));

Tiempos para 10,000 bucles en cadenas simples con espacios en blanco, nuevas líneas y pestañas

  • split / join = 60 milisegundos
  • linq chararray = 94 milisegundos
  • expresiones regulares = 437 milisegundos

Mejore esto envolviéndolo en un método para darle significado, y también conviértalo en un método de extensión mientras estamos en ello ...

public static string RemoveWhitespace(this string str) { return string.Join("", str.Split(default(string[]), StringSplitOptions.RemoveEmptyEntries)); }


Necesitaba reemplazar los espacios en blanco en una cadena con espacios, pero no espacios duplicados. Por ejemplo, necesitaba convertir algo como lo siguiente:

"a b c/r/n d/t/t/t e"

a

"a b c d e"

Utilicé el siguiente método

private static string RemoveWhiteSpace(string value) { if (value == null) { return null; } var sb = new StringBuilder(); var lastCharWs = false; foreach (var c in value) { if (char.IsWhiteSpace(c)) { if (lastCharWs) { continue; } sb.Append('' ''); lastCharWs = true; } else { sb.Append(c); lastCharWs = false; } } return sb.ToString(); }


Nosotros podemos usar:

public static string RemoveWhitespace(this string input) { if (input == null) return null; return new string(input.ToCharArray() .Where(c => !Char.IsWhiteSpace(c)) .ToArray()); }


Podemos usar System.Linq y podemos hacerlo en una línea:

string text = "My text with white spaces..."; text = new string(text.ToList().Where(c => c != '' '').ToArray());


Pruebe el método de reemplazo de la cadena en C #.

XML.Replace(" ", string.Empty);


Regex es una exageración; solo usa la extensión en la cadena (gracias Henk). Esto es trivial y debería haber sido parte del marco. De todos modos, aquí está mi implementación:

public static partial class Extension { public static string RemoveWhiteSpace(this string self) { return new string(self.Where(c => !Char.IsWhiteSpace(c)).ToArray()); } }


Si necesita un rendimiento excelente, debe evitar LINQ y las expresiones regulares en este caso. Hice algunas evaluaciones comparativas de rendimiento, y parece que si quieres eliminar los espacios en blanco desde el principio y el final de la cadena, string.Trim () es tu función definitiva.

Si necesita eliminar todos los espacios en blanco de una cadena, el siguiente método funciona más rápido de todo lo que se ha publicado aquí:

public static string RemoveWhitespace(this string input) { int j = 0, inputlen = input.Length; char[] newarr = new char[inputlen]; for (int i = 0; i < inputlen; ++i) { char tmp = input[i]; if (!char.IsWhiteSpace(tmp)) { newarr[j] = tmp; ++j; } } return new String(newarr, 0, j); }


Sobre la base de la respuesta de Henks , he creado algunos métodos de prueba con su respuesta y algunos métodos más optimizados. Encontré que los resultados difieren según el tamaño de la cadena de entrada. Por lo tanto, he probado con dos conjuntos de resultados. En el método más rápido, la fuente vinculada tiene una forma aún más rápida. Pero, como se caracteriza por ser inseguro, lo he dejado fuera.

Resultados de cadena de entrada larga:

  1. InPlaceCharArray: 2021 ms ( respuesta de Sunsetquest ) - ( Fuente original )
  2. Lector de cuerdas: 6082 ms
  3. LINQ usando char nativo. IsWhitespace: 7357 ms
  4. LINQ: 7746 ms ( respuesta de Henk )
  5. ForLoop: 32320 ms
  6. RegexCompiled: 37157 ms
  7. Regex: 42940 ms

Resultados cortos de la cadena de entrada:

  1. InPlaceCharArray: 108 ms ( respuesta de Sunsetquest ) - ( Fuente original )
  2. Lector de cuerdas: 327 ms
  3. ForLoop: 343 ms
  4. LINQ usando char nativo. IsWhitespace: 624 ms
  5. LINQ: 645ms ( respuesta de Henk )
  6. RegexCompiled: 1671 ms
  7. Regex: 2599 ms

Código :

public class RemoveWhitespace { public static string RemoveStringReader(string input) { var s = new StringBuilder(input.Length); // (input.Length); using (var reader = new StringReader(input)) { int i = 0; char c; for (; i < input.Length; i++) { c = (char)reader.Read(); if (!char.IsWhiteSpace(c)) { s.Append(c); } } } return s.ToString(); } public static string RemoveLinqNativeCharIsWhitespace(string input) { return new string(input.ToCharArray() .Where(c => !char.IsWhiteSpace(c)) .ToArray()); } public static string RemoveLinq(string input) { return new string(input.ToCharArray() .Where(c => !Char.IsWhiteSpace(c)) .ToArray()); } public static string RemoveRegex(string input) { return Regex.Replace(input, @"/s+", ""); } private static Regex compiled = new Regex(@"/s+", RegexOptions.Compiled); public static string RemoveRegexCompiled(string input) { return compiled.Replace(input, ""); } public static string RemoveForLoop(string input) { for (int i = input.Length - 1; i >= 0; i--) { if (char.IsWhiteSpace(input[i])) { input = input.Remove(i, 1); } } return input; } public static string RemoveInPlaceCharArray(string input) { var len = input.Length; var src = input.ToCharArray(); int dstIdx = 0; for (int i = 0; i < len; i++) { var ch = src[i]; switch (ch) { case ''/u0020'': case ''/u00A0'': case ''/u1680'': case ''/u2000'': case ''/u2001'': case ''/u2002'': case ''/u2003'': case ''/u2004'': case ''/u2005'': case ''/u2006'': case ''/u2007'': case ''/u2008'': case ''/u2009'': case ''/u200A'': case ''/u202F'': case ''/u205F'': case ''/u3000'': case ''/u2028'': case ''/u2029'': case ''/u0009'': case ''/u000A'': case ''/u000B'': case ''/u000C'': case ''/u000D'': case ''/u0085'': continue; default: src[dstIdx++] = ch; break; } } return new string(src, 0, dstIdx); } }

Pruebas :

[TestFixture] public class Test { // Short input //private const string input = "123 123 /t 1adc /n 222"; //private const string expected = "1231231adc222"; // Long input private const string input = "123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222123 123 /t 1adc /n 222"; private const string expected = "1231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc222"; private const int iterations = 1000000; [Test] public void RemoveInPlaceCharArray() { string s = null; var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) { s = RemoveWhitespace.RemoveInPlaceCharArray(input); } stopwatch.Stop(); Console.WriteLine("InPlaceCharArray: " + stopwatch.ElapsedMilliseconds + " ms"); Assert.AreEqual(expected, s); } [Test] public void RemoveStringReader() { string s = null; var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) { s = RemoveWhitespace.RemoveStringReader(input); } stopwatch.Stop(); Console.WriteLine("String reader: " + stopwatch.ElapsedMilliseconds + " ms"); Assert.AreEqual(expected, s); } [Test] public void RemoveLinqNativeCharIsWhitespace() { string s = null; var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) { s = RemoveWhitespace.RemoveLinqNativeCharIsWhitespace(input); } stopwatch.Stop(); Console.WriteLine("LINQ using native char.IsWhitespace: " + stopwatch.ElapsedMilliseconds + " ms"); Assert.AreEqual(expected, s); } [Test] public void RemoveLinq() { string s = null; var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) { s = RemoveWhitespace.RemoveLinq(input); } stopwatch.Stop(); Console.WriteLine("LINQ: " + stopwatch.ElapsedMilliseconds + " ms"); Assert.AreEqual(expected, s); } [Test] public void RemoveRegex() { string s = null; var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) { s = RemoveWhitespace.RemoveRegex(input); } stopwatch.Stop(); Console.WriteLine("Regex: " + stopwatch.ElapsedMilliseconds + " ms"); Assert.AreEqual(expected, s); } [Test] public void RemoveRegexCompiled() { string s = null; var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) { s = RemoveWhitespace.RemoveRegexCompiled(input); } stopwatch.Stop(); Console.WriteLine("RegexCompiled: " + stopwatch.ElapsedMilliseconds + " ms"); Assert.AreEqual(expected, s); } [Test] public void RemoveForLoop() { string s = null; var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) { s = RemoveWhitespace.RemoveForLoop(input); } stopwatch.Stop(); Console.WriteLine("ForLoop: " + stopwatch.ElapsedMilliseconds + " ms"); Assert.AreEqual(expected, s); } }


Solo una alternativa porque se ve bastante bien :) - NOTA: La respuesta de Henks es la más rápida de estas.

input.ToCharArray() .Where(c => !Char.IsWhiteSpace(c)) .Select(c => c.ToString()) .Aggregate((a, b) => a + b);

Probando 1,000,000 de bucles en "This is a simple Test"

Este método = 1.74 segundos.
Regex = 2.58 segundos
new String (Henks) = 0.82


Tengo una forma alternativa sin regexp, y parece funcionar bastante bien. Es una continuación de la respuesta de Brandon Moretz:

public static string RemoveWhitespace(this string input) { return new string(input.ToCharArray() .Where(c => !Char.IsWhiteSpace(c)) .ToArray()); }

Lo probé en una prueba unitaria simple:

[Test] [TestCase("123 123 1adc /n 222", "1231231adc222")] public void RemoveWhiteSpace1(string input, string expected) { string s = null; for (int i = 0; i < 1000000; i++) { s = input.RemoveWhitespace(); } Assert.AreEqual(expected, s); } [Test] [TestCase("123 123 1adc /n 222", "1231231adc222")] public void RemoveWhiteSpace2(string input, string expected) { string s = null; for (int i = 0; i < 1000000; i++) { s = Regex.Replace(input, @"/s+", ""); } Assert.AreEqual(expected, s); }

Para 1,000,000 intentos, la primera opción (sin regexp) se ejecuta en menos de un segundo (700 ms en mi máquina), y la segunda toma 3.5 segundos.