vacios una quitar ignorar frase espacios espacio eliminar doble devolver dada blanco c# string replace whitespace removing-whitespace

una - c#La forma más rápida de eliminar espacios en blanco adicionales



quitar espacios en blanco al final c# (23)

¿Cuál es la forma más rápida de reemplazar espacios en blanco adicionales en un espacio en blanco?
p.ej

de

foo bar

a

foo bar


¡No hay necesidad de código complejo! Aquí hay un código simple que eliminará cualquier duplicado:

public static String RemoveCharOccurence(String s, char[] remove) { String s1 = s; foreach(char c in remove) { s1 = RemoveCharOccurence(s1, c); } return s1; } public static String RemoveCharOccurence(String s, char remove) { StringBuilder sb = new StringBuilder(s.Length); Boolean removeNextIfMatch = false; foreach(char c in s) { if(c == remove) { if(removeNextIfMatch) continue; else removeNextIfMatch = true; } else removeNextIfMatch = false; sb.Append(c); } return sb.ToString(); }


¿La vía más rápida? Itere sobre la cadena y construya una segunda copia en un caracter de StringBuilder por caracter, solo copie un espacio para cada grupo de espacios.

Las variantes Replace más fáciles de escribir crearán una carga de cadenas adicionales (o desperdiciará tiempo creando el DFA regex).

Editar con resultados de comparación:

Usando http://ideone.com/h6pw3 , con n = 50 (tuve que reducirlo en ideone porque me tomó tanto tiempo que tuvieron que matar mi proceso), obtengo:

Regex: 7771ms.

Stringbuilder: 894ms.

Que es, de hecho, como se esperaba, Regex es terriblemente ineficiente para algo tan simple.


¿Me estoy perdiendo de algo? Se me ocurrió esto:

// Input: "HELLO BEAUTIFUL WORLD!" private string NormalizeWhitespace(string inputStr) { // First split the string on the spaces but exclude the spaces themselves // Using the input string the length of the array will be 3. If the spaces // were not filtered out they would be included in the array var splitParts = inputStr.Split('' '').Where(x => x != "").ToArray(); // Now iterate over the parts in the array and add them to the return // string. If the current part is not the last part, add a space after. for (int i = 0; i < splitParts.Count(); i++) { retVal += splitParts[i]; if (i != splitParts.Count() - 1) { retVal += " "; } } return retVal; } // Would return "HELLO BEAUTIFUL WORLD!"

Sé que estoy creando una segunda cadena aquí para devolverla y crear la matriz splitParts. Pensé que esto es bastante directo. Tal vez no estoy teniendo en cuenta algunos de los posibles escenarios.


Acabo de azotar esto, aunque aún no lo he probado. Pero sentí que era elegante y evita la expresión regular:

/// <summary> /// Removes extra white space. /// </summary> /// <param name="s"> /// The string /// </param> /// <returns> /// The string, with only single white-space groupings. /// </returns> public static string RemoveExtraWhiteSpace(this string s) { if (s.Length == 0) { return string.Empty; } var stringBuilder = new StringBuilder(); var whiteSpaceCount = 0; foreach (var character in s) { if (char.IsWhiteSpace(character)) { whiteSpaceCount++; } else { whiteSpaceCount = 0; } if (whiteSpaceCount > 1) { continue; } stringBuilder.Append(character); } return stringBuilder.ToString(); }


Algunos requisitos no son claros en esta pregunta que merecen un poco de reflexión.

  1. ¿Desea un único carácter de espacio en blanco inicial o final?
  2. Cuando reemplazas todo el espacio en blanco con un solo carácter, ¿quieres que ese carácter sea consistente? (es decir, muchas de estas soluciones reemplazarían a / t / t con / t y '''' con ''''.

Esta es una versión muy eficiente que reemplaza todo el espacio en blanco con un solo espacio y elimina cualquier espacio en blanco inicial y final antes del ciclo for.

public static string WhiteSpaceToSingleSpaces(string input) { if (input.Length < 2) return input; StringBuilder sb = new StringBuilder(); input = input.Trim(); char lastChar = input[0]; bool lastCharWhiteSpace = false; for (int i = 1; i < input.Length; i++) { bool whiteSpace = char.IsWhiteSpace(input[i]); //Skip duplicate whitespace characters if (whiteSpace && lastCharWhiteSpace) continue; //Replace all whitespace with a single space. if (whiteSpace) sb.Append('' ''); else sb.Append(input[i]); //Keep track of the last character''s whitespace status lastCharWhiteSpace = whiteSpace; } return sb.ToString(); }


Es muy simple, solo usa el método .Replace() :

string words = "Hello world!"; words = words.Replace("//s+", " ");

Salida >>> "¡Hola mundo!"


Este pedazo de código funciona bien. No he medido el rendimiento.

string text = " hello - world, here we go !!! a bc "; string.Join(" ", text.Split().Where(x => x != "")); // Output // "hello - world, here we go !!! a bc"


Esto es divertido, pero en mi PC el siguiente método es tan rápido como el enfoque StringBulder de Sergey Povalyaev: (~ 282ms para 1000 repeticiones, 10k series de src). Sin embargo, no estoy seguro sobre el uso de la memoria.

string RemoveExtraWhiteSpace(string src, char[] wsChars){ return string.Join(" ",src.Split(wsChars, StringSplitOptions.RemoveEmptyEntries)); }

Obviamente funciona bien con cualquier carácter, no solo espacios.

Aunque esto no es lo que solicitó OP, pero si lo que realmente necesita es reemplazar caracteres consecutivos específicos en una cadena con una sola instancia, puede usar este método relativamente eficiente:

string RemoveDuplicateChars(string src, char[] dupes){ var sd = (char[])dupes.Clone(); Array.Sort(sd); var res = new StringBuilder(src.Length); for(int i = 0; i<src.Length; i++){ if( i==0 || src[i]!=src[i-1] || Array.BinarySearch(sd,src[i])<0){ res.Append(src[i]); } } return res.ToString(); }


He intentado usar StringBuilder para:

  1. eliminar subcadenas de espacios en blanco adicionales
  2. acepte que los personajes crucen la secuencia original, como sugiere Blindy

Este es el mejor equilibrio de rendimiento y legibilidad que he encontrado (utilizando 100.000 ejecuciones de tiempo de iteración). Algunas veces, esta prueba es más rápida que una versión menos legible, como máximo un 5% más lenta. En mi cadena de prueba pequeña, Regex toma 4.24 veces más tiempo.

public static string RemoveExtraWhitespace(string str) { var sb = new StringBuilder(); var prevIsWhitespace = false; foreach (var ch in str) { var isWhitespace = char.IsWhiteSpace(ch); if (prevIsWhitespace && isWhitespace) { continue; } sb.Append(ch); prevIsWhitespace = isWhitespace; } return sb.ToString(); }


Necesitaba uno de estos para cuerdas más grandes y se me ocurrió la siguiente rutina.

Cualquier espacio en blanco consecutivo (incluyendo pestañas, líneas nuevas) se reemplaza con lo que esté en normalizeTo . El espacio en blanco inicial / final se elimina.

Es alrededor de 8 veces más rápido que un RegEx con mis cadenas de caracteres 5k-> 5mil.

internal static string NormalizeWhiteSpace(string input, char normalizeTo = '' '') { if (string.IsNullOrEmpty(input)) return string.Empty; int current = 0; char[] output = new char[input.Length]; bool skipped = false; foreach (char c in input.ToCharArray()) { if (char.IsWhiteSpace(c)) { if (!skipped) { if (current > 0) output[current++] = normalizeTo; skipped = true; } } else { skipped = false; output[current++] = c; } } return new string(output, 0, skipped ? current - 1 : current); }


No es rápido, pero si la simplicidad ayuda, esto funciona:

while (text.Contains(" ")) text=text.Replace(" ", " ");


Para aquellos que solo quieren copiar-pase y seguir:

private string RemoveExcessiveWhitespace(string value) { if (value == null) { return null; } var builder = new StringBuilder(); var ignoreWhitespace = false; foreach (var c in value) { if (!ignoreWhitespace || c != '' '') { builder.Append(c); } ignoreWhitespace = c == '' ''; } return builder.ToString(); }


Puedes usar un regex:

static readonly Regex trimmer = new Regex(@"/s/s+"); s = trimmer.Replace(s, " ");

Para un rendimiento adicional, pase RegexOptions.Compiled .


Sé que esto es realmente antiguo, pero la forma más fácil de compaginar espacios en blanco (reemplazar cualquier carácter de espacio en blanco recurrente con un único carácter "espacio") es el siguiente:

public static string CompactWhitespace(string astring) { if (!string.IsNullOrEmpty(astring)) { bool found = false; StringBuilder buff = new StringBuilder(); foreach (char chr in astring.Trim()) { if (char.IsWhiteSpace(chr)) { if (found) { continue; } found = true; buff.Append('' ''); } else { if (found) { found = false; } buff.Append(chr); } } return buff.ToString(); } return string.Empty; }


Un poco tarde, pero he hecho algunos benchmarking para obtener la forma más rápida de eliminar espacios en blanco adicionales. Si hay respuestas más rápidas, me encantaría agregarlas.

Resultados:

  1. NormalizeWhiteSpaceForLoop: 156 ms ( por mí: de mi respuesta al eliminar todos los espacios en blanco )
  2. NormalizeWhiteSpace: 267 ms ( por Alex K. )
  3. RegexCompilado: 1950 ms ( por SLaks )
  4. Regex: 2261 ms ( por SLaks )

Código:

public class RemoveExtraWhitespaces { public static string WithRegex(string text) { return Regex.Replace(text, @"/s+", " "); } public static string WithRegexCompiled(Regex compiledRegex, string text) { return compiledRegex.Replace(text, " "); } public static string NormalizeWhiteSpace(string input) { if (string.IsNullOrEmpty(input)) return string.Empty; int current = 0; char[] output = new char[input.Length]; bool skipped = false; foreach (char c in input.ToCharArray()) { if (char.IsWhiteSpace(c)) { if (!skipped) { if (current > 0) output[current++] = '' ''; skipped = true; } } else { skipped = false; output[current++] = c; } } return new string(output, 0, current); } public static string NormalizeWhiteSpaceForLoop(string input) { int len = input.Length, index = 0, i = 0; var src = input.ToCharArray(); bool skip = false; char ch; for (; i < len; i++) { 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'': if (skip) continue; src[index++] = ch; skip = true; continue; default: skip = false; src[index++] = ch; continue; } } return new string(src, 0, index); } }

Pruebas:

[TestFixture] public class RemoveExtraWhitespacesTest { private const string _text = "foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo "; private const string _expected = "foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo foo bar foobar moo "; private const int _iterations = 10000; [Test] public void Regex() { var result = TimeAction("Regex", () => RemoveExtraWhitespaces.WithRegex(_text)); Assert.AreEqual(_expected, result); } [Test] public void RegexCompiled() { var compiledRegex = new Regex(@"/s+", RegexOptions.Compiled); var result = TimeAction("RegexCompiled", () => RemoveExtraWhitespaces.WithRegexCompiled(compiledRegex, _text)); Assert.AreEqual(_expected, result); } [Test] public void NormalizeWhiteSpace() { var result = TimeAction("NormalizeWhiteSpace", () => RemoveExtraWhitespaces.NormalizeWhiteSpace(_text)); Assert.AreEqual(_expected, result); } [Test] public void NormalizeWhiteSpaceForLoop() { var result = TimeAction("NormalizeWhiteSpaceForLoop", () => RemoveExtraWhitespaces.NormalizeWhiteSpaceForLoop(_text)); Assert.AreEqual(_expected, result); } public string TimeAction(string name, Func<string> func) { var timer = Stopwatch.StartNew(); string result = string.Empty; ; for (int i = 0; i < _iterations; i++) { result = func(); } timer.Stop(); Console.WriteLine(string.Format("{0}: {1} ms", name, timer.ElapsedMilliseconds)); return result; } }


Utilizo los siguientes métodos: manejan todos los caracteres del espacio en blanco, no solo los espacios, recortan los espacios en blanco anteriores y posteriores , eliminan los espacios en blanco adicionales , y todos los espacios en blanco se reemplazan por caracteres espaciales (por lo que tenemos un separador de espacio uniforme). Y estos métodos son rápidos .

public static String CompactWhitespaces( String s ) { StringBuilder sb = new StringBuilder( s ); CompactWhitespaces( sb ); return sb.ToString(); } public static void CompactWhitespaces( StringBuilder sb ) { if( sb.Length == 0 ) return; // set [start] to first not-whitespace char or to sb.Length int start = 0; while( start < sb.Length ) { if( Char.IsWhiteSpace( sb[ start ] ) ) start++; else break; } // if [sb] has only whitespaces, then return empty string if( start == sb.Length ) { sb.Length = 0; return; } // set [end] to last not-whitespace char int end = sb.Length - 1; while( end >= 0 ) { if( Char.IsWhiteSpace( sb[ end ] ) ) end--; else break; } // compact string int dest = 0; bool previousIsWhitespace = false; for( int i = start; i <= end; i++ ) { if( Char.IsWhiteSpace( sb[ i ] ) ) { if( !previousIsWhitespace ) { previousIsWhitespace = true; sb[ dest ] = '' ''; dest++; } } else { previousIsWhitespace = false; sb[ dest ] = sb[ i ]; dest++; } } sb.Length = dest; }


prueba esto:

System.Text.RegularExpressions.Regex.Replace(input, @"/s+", " ");


puede usar indexOf para obtener primero donde comienzan las secuencias de espacios en blanco, luego use el método de reemplazo para cambiar el espacio en blanco a "". A partir de ahí, puede usar el índice que tomó y colocar un carácter de espacio en blanco en ese punto.


public static string RemoveExtraSpaces(string input) { input = input.Trim(); string output = ""; bool WasLastCharSpace = false; for (int i = 0; i < input.Length; i++) { if (input[i] == '' '' && WasLastCharSpace) continue; WasLastCharSpace = input[i] == '' ''; output += input[i]; } return output; }


public string GetCorrectString(string IncorrectString) { string[] strarray = IncorrectString.Split('' ''); var sb = new StringBuilder(); foreach (var str in strarray) { if (str != string.Empty) { sb.Append(str).Append('' ''); } } return sb.ToString().Trim(); }


string q = " Hello how are you doing?"; string a = String.Join(" ", q.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries));


string text = "foo bar"; text = Regex.Replace(text, @"/s+", " "); // text = "foo bar"

Esta solución funciona con espacios, pestañas y nueva línea. Si solo desea espacios, reemplace ''/ s'' por ''''.


string yourWord = "beep boop baap beep boop baap beep"; yourWord = yourWord .Replace(" ", " |").Replace("| ", "").Replace("|", "");