2009-08-14 18 views
90

Digamos que tengo una cadena como:Como reemplazar múltiples espacios en blanco con un espacio en blanco

"Hello  how are you   doing?" 

me gustaría una función que convierte múltiples espacios en un mismo espacio.

Así que me gustaría tener:

"Hello how are you doing?" 

Sé que podría utilizar expresiones regulares o llame

string s = "Hello  how are you   doing?".replace(" "," "); 

Pero tendría que llamar varias veces para asegurarse de que todos los espacios en blanco consecutivos se reemplazan con solamente uno.

¿Ya hay un método incorporado para esto?

+0

Podría aclarar: ¿solo se trata de espacios, o "todos" espacios en blanco? –

+0

¿Y desea que espacios en blanco que no sean espacios se conviertan en espacios? –

+0

Me refiero a que todos los espacios en blanco de la serie deberían ser como máximo 1 – Matt

Respuesta

166
string cleanedString = System.Text.RegularExpressions.Regex.Replace(dirtyString,@"\s+"," "); 
+2

El uso de una expresión regular introduce una gran cantidad de sobrecarga que no es necesaria. –

+38

imo, evitando la expresión regular si está cómodo con ellos es la optimización prematura –

+8

Si su aplicación no es de tiempo crítico, puede permitirse el procesamiento de 1 microsegundo de sobrecarga. – Daniel

16

Un expressoin regular sería la forma más fácil. Si escribe la expresión regular de la forma correcta, no necesitará varias llamadas.

Cambio a esto:

string s = System.Text.RegularExpressions.Regex.Replace(s, @"\s{2,}", " "); 
+1

Esta respuesta debería estar en la parte superior, me llevó 10 looong segundos encontrar la respuesta más útil –

1
Regex regex = new Regex(@"\W+"); 
string outputString = regex.Replace(inputString, " "); 
+0

Esto reemplaza todos los caracteres no verbales con espacio. Por lo tanto, también reemplazaría elementos como corchetes y comillas, etc., que podrían no ser lo que usted desea. – Herman

-1

No hay manera integrada para realizar esta acción. Puede probar esto:

private static readonly char[] whitespace = new char[] { ' ', '\n', '\t', '\r', '\f', '\v' }; 
public static string Normalize(string source) 
{ 
    return String.Join(" ", source.Split(whitespace, StringSplitOptions.RemoveEmptyEntries)); 
} 

Esto eliminará ataque y de salida, así como whitespce colapso cualquier espacio en blanco interior de un solo espacio en blanco. Si realmente solo quieres colapsar espacios, entonces las soluciones que usan una expresión regular son mejores; de lo contrario, esta solución es mejor. (Véase la analysis realizado por Jon Skeet.)

+6

Si la expresión regular se compila y almacena en caché, no estoy seguro de que tenga más sobrecarga que dividir y unir, lo que podría crear * cargas * de cadenas de basura intermedias. ¿Has realizado puntos de referencia cuidadosos de ambos enfoques antes de asumir que tu camino es más rápido? –

+1

el espacio en blanco no está declarado aquí –

+3

Hablando de sobrecarga, ¿por qué llamas a 'source.ToCharArray()' y luego descartas el resultado? –

17

Si bien las respuestas existentes están muy bien, me gustaría señalar un enfoque que no lo hace trabajo:

public static string DontUseThisToCollapseSpaces(string text) 
{ 
    while (text.IndexOf(" ") != -1) 
    { 
     text = text.Replace(" ", " "); 
    } 
    return text; 
} 

Esto puede bucle para siempre. ¿Alguien quiere adivinar por qué? (Solo me encontré con esto cuando se lo preguntaron como una pregunta de grupo de noticias hace unos años ... alguien realmente lo encontró como un problema.)

+0

Creo que recuerdo esta pregunta hecha hace un tiempo en SO. IndexOf ignora ciertos caracteres que Replace no lo hace. Entonces, el doble espacio siempre estuvo ahí, nunca se eliminó. – Brandon

+18

Es porque IndexOf ignora algunos caracteres Unicode, el culprado específico en este caso es algún carácter asiático iirc. Hmm, no anulador de ancho cero según Google. – ahawker

+3

Y Hawker obtiene el premio :) –

4

Como ya se señaló, esto se hace fácilmente mediante una expresión regular. Solo agregaré que es posible que desee agregar un .trim() a eso para deshacerse del espacio en blanco inicial/final.

51

Esta pregunta no es tan simple como lo han hecho otros carteles (y como originalmente pensé que era), porque la pregunta no es tan precisa como debe ser.

Hay una diferencia entre "espacio" y "espacio en blanco". Si solo significa espacios medios, entonces debe usar una expresión regular de " {2,}". Si se refiere a cualquier espacio en blanco, esa es una cuestión diferente. ¿Debería todos los espacios en blanco convertirse a espacios? ¿Qué debería pasarle al espacio al principio y al final?

Para el punto de referencia a continuación, he supuesto que solo le importan los espacios, y no desea hacer nada en espacios individuales, ni siquiera al principio y al final.

Tenga en cuenta que la corrección es casi siempre más importante que el rendimiento.El hecho de que la solución Split/Join elimine cualquier espacio en blanco inicial/final (incluso solo espacios individuales) es incorrecto en cuanto a sus requisitos específicos (que pueden estar incompletos, por supuesto).

El índice de referencia usa MiniBench.

using System; 
using System.Text.RegularExpressions; 
using MiniBench; 

internal class Program 
{ 
    public static void Main(string[] args) 
    { 

     int size = int.Parse(args[0]); 
     int gapBetweenExtraSpaces = int.Parse(args[1]); 

     char[] chars = new char[size]; 
     for (int i=0; i < size/2; i += 2) 
     { 
      // Make sure there actually *is* something to do 
      chars[i*2] = (i % gapBetweenExtraSpaces == 1) ? ' ' : 'x'; 
      chars[i*2 + 1] = ' '; 
     } 
     // Just to make sure we don't have a \0 at the end 
     // for odd sizes 
     chars[chars.Length-1] = 'y'; 

     string bigString = new string(chars); 
     // Assume that one form works :) 
     string normalized = NormalizeWithSplitAndJoin(bigString); 


     var suite = new TestSuite<string, string>("Normalize") 
      .Plus(NormalizeWithSplitAndJoin) 
      .Plus(NormalizeWithRegex) 
      .RunTests(bigString, normalized); 

     suite.Display(ResultColumns.All, suite.FindBest()); 
    } 

    private static readonly Regex MultipleSpaces = 
     new Regex(@" {2,}", RegexOptions.Compiled); 

    static string NormalizeWithRegex(string input) 
    { 
     return MultipleSpaces.Replace(input, " "); 
    } 

    // Guessing as the post doesn't specify what to use 
    private static readonly char[] Whitespace = 
     new char[] { ' ' }; 

    static string NormalizeWithSplitAndJoin(string input) 
    { 
     string[] split = input.Split 
      (Whitespace, StringSplitOptions.RemoveEmptyEntries); 
     return string.Join(" ", split); 
    } 
} 

Unos ensayos:

c:\Users\Jon\Test>test 1000 50 
============ Normalize ============ 
NormalizeWithSplitAndJoin 1159091 0:30.258 22.93 
NormalizeWithRegex  26378882 0:30.025 1.00 

c:\Users\Jon\Test>test 1000 5 
============ Normalize ============ 
NormalizeWithSplitAndJoin 947540 0:30.013 1.07 
NormalizeWithRegex  1003862 0:29.610 1.00 


c:\Users\Jon\Test>test 1000 1001 
============ Normalize ============ 
NormalizeWithSplitAndJoin 1156299 0:29.898 21.99 
NormalizeWithRegex  23243802 0:27.335 1.00 

Aquí el primer número es el número de iteraciones, el segundo es el tiempo necesario, y la tercera es una escala de puntuación con 1,0 es la mejor.

Esto muestra que en al menos algunos casos (incluido este) una expresión regular puede superan a la solución de Split/Join, a veces por un margen muy significativo.

Sin embargo, si cambia a un requisito de "todos los espacios en blanco", Split/Join parece que parece ganar. Como suele ser el caso, el diablo está en el detalle ...

+1

Gran análisis. Por lo tanto, parece que ambos estábamos correctos en diversos grados. El código en mi respuesta fue tomado de una función más grande que tiene la capacidad de normalizar todos los espacios en blanco y/o controlar caracteres desde dentro de una cadena y desde el principio y el final. –

+1

Con solo los caracteres en blanco Específicamente, en la mayoría de mis pruebas, la expresión regular y el Split/Join eran casi iguales: S/J tenía un pequeño y pequeño beneficio, a costa de la corrección y la complejidad. Por esas razones, normalmente prefería la expresión regular. me malinterpreten, estoy lejos de ser un fanático de la expresión regular, pero no me gusta escribir códigos más complejos por el rendimiento sin probar realmente el rendimiento primero. –

+0

NormalizeWithSplitAndJoin creará mucho más atuendo edad, es difícil saber si un problema real será golpeado más tiempo de GC que el valor de referencia. –

0

solución más pequeña:

var regExp =/\ s +/g, newString = oldString.replace (regExp,' ');

3

Estoy compartiendo lo que uso, porque parece que he encontrado algo diferente. He estado usando esto por un tiempo y es lo suficientemente rápido para mí. No estoy seguro de cómo se compara con los demás. Lo uso en un escritor de archivos delimitado y ejecuto grandes tablas de datos un campo a la vez a través de él.

public static string NormalizeWhiteSpace(string S) 
    { 
     string s = S.Trim(); 
     bool iswhite = false; 
     int iwhite; 
     int sLength = s.Length; 
     StringBuilder sb = new StringBuilder(sLength); 
     foreach(char c in s.ToCharArray()) 
     { 
      if(Char.IsWhiteSpace(c)) 
      { 
       if (iswhite) 
       { 
        //Continuing whitespace ignore it. 
        continue; 
       } 
       else 
       { 
        //New WhiteSpace 

        //Replace whitespace with a single space. 
        sb.Append(" "); 
        //Set iswhite to True and any following whitespace will be ignored 
        iswhite = true; 
       } 
      } 
      else 
      { 
       sb.Append(c.ToString()); 
       //reset iswhitespace to false 
       iswhite = false; 
      } 
     } 
     return sb.ToString(); 
    } 
1

VB.NET Linha.Split (" ") .ToList(). Donde (función (x) x <>" ") .ToArray

C# Linha.Split ("") .ToList(). Cuando (x => x <> " ") .ToArray()

disfrutar de la potencia de LINQ = D

+0

¡Exactamente! Para mí, este es el enfoque más elegante, también. Entonces para el registro, en C# sería: 'string.Join (" ", myString.Split ('') .Where (s => s! =" ") .ToArray())' – Efrain

+0

Mejora menor en el 'Split' para capturar todos los espacios en blanco y eliminar la cláusula' Where': 'myString.Split (null como char [], StringSplitOptions.RemoveEmptyEntries)' – David

2

Utilizando el programa de prueba que Jon Skeet publicada, traté de ver si podría obtener un bucle escrito a mano para correr más rápido.
puedo vencer NormalizeWithSplitAndJoin cada vez, pero sólo vencer a NormalizeWithRegex con entradas de 1000, 5.

static string NormalizeWithLoop(string input) 
{ 
    StringBuilder output = new StringBuilder(input.Length); 

    char lastChar = '*'; // anything other then space 
    for (int i = 0; i < input.Length; i++) 
    { 
     char thisChar = input[i]; 
     if (!(lastChar == ' ' && thisChar == ' ')) 
      output.Append(thisChar); 

     lastChar = thisChar; 
    } 

    return output.ToString(); 
} 

no he mirado el código máquina de la fluctuación de fase produce, sin embargo espero que el problema es el tiempo que tarda el llamar a StringBuilder.Append() y para hacerlo mucho mejor necesitaría el uso de un código inseguro.

¡Así que Regex.Replace() es muy rápido y difícil de superar!

2

Aquí está la solución con la que trabajo. Sin RegEx y String.Split.

public static string TrimWhiteSpace(this string Value) 
{ 
    StringBuilder sbOut = new StringBuilder(); 
    if (!string.IsNullOrEmpty(Value)) 
    { 
     bool IsWhiteSpace = false; 
     for (int i = 0; i < Value.Length; i++) 
     { 
      if (char.IsWhiteSpace(Value[i])) //Comparion with WhiteSpace 
      { 
       if (!IsWhiteSpace) //Comparison with previous Char 
       { 
        sbOut.Append(Value[i]); 
        IsWhiteSpace = true; 
       } 
      } 
      else 
      { 
       IsWhiteSpace = false; 
       sbOut.Append(Value[i]); 
      } 
     } 
    } 
    return sbOut.ToString(); 
} 

para que pueda:

string cleanedString = dirtyString.TrimWhiteSpace(); 
1

Un rápido removedor de espacios en blanco extra ... Este es el más rápido y se basa en la copia de Felipe Machado en el lugar.

static string InPlaceCharArray(string str) 
{ 
    var len = str.Length; 
    var src = str.ToCharArray(); 
    int dstIdx = 0; 
    bool lastWasWS = false; 
    for (int i = 0; i < len; i++) 
    { 
     var ch = src[i]; 
     if (src[i] == '\u0020') 
     { 
      if (lastWasWS == false) 
      { 
       src[dstIdx++] = ch; 
       lastWasWS = true; 
      } 
     } 
     else 
     { 
      lastWasWS = false; 
      src[dstIdx++] = ch; 
     } 
    } 
    return new string(src, 0, dstIdx); 
} 

Los puntos de referencia ...

InPlaceCharArraySpaceOnly por Felipe Machado on CodeProject 2015 y modificado por Sunsetquest para la eliminación de multi-espacio. Tiempo: 3,75 garrapatas

InPlaceCharArray por Felipe Machado 2015 y ligeramente modificados por Sunsetquest para la eliminación de multi-espacio. Tiempo 6,50 garrapatas (soporta pestañas también)

SplitAndJoinOnSpace por Jon Skeet. Tiempo: 13,25 garrapatas

StringBuilder por fubo Tiempo: 13,5 garrapatas (soporta pestañas también)

Regex con compilación por Jon Skeet. Tiempo: 17 Las garrapatas

StringBuilder por Tiempo: 30,5 garrapatas

Regex con no compilar por Brandon Tiempo: 63,25 garrapatas

StringBuilder por user214147 Time : 77.125 Ticks

expresiones regulares con los no-compilar Tim Hoolihan Tiempo: 147.25 garrapatas

El código de referencia ...

using System; 
using System.Text.RegularExpressions; 
using System.Diagnostics; 
using System.Threading; 
using System.Text; 

static class Program 
{ 
    public static void Main(string[] args) 
    { 
    long seed = ConfigProgramForBenchmarking(); 

    Stopwatch sw = new Stopwatch(); 

    string warmup = "This is a Warm up function for best benchmark results." + seed; 
    string input1 = "Hello World, how are you   doing?" + seed; 
    string input2 = "It\twas\t \tso nice to\t\t see you \tin 1950. \t" + seed; 
    string correctOutput1 = "Hello World, how are you doing?" + seed; 
    string correctOutput2 = "It\twas\tso nice to\tsee you in 1950. " + seed; 
    string output1,output2; 

    //warm-up timer function 
    sw.Restart(); 
    sw.Stop(); 

    sw.Restart(); 
    sw.Stop(); 
    long baseVal = sw.ElapsedTicks; 

    // InPlace Replace by Felipe Machado but modified by Ryan for multi-space removal (http://www.codeproject.com/Articles/1014073/Fastest-method-to-remove-all-whitespace-from-Strin) 
    output1 = InPlaceCharArraySpaceOnly (warmup); 
    sw.Restart(); 
    output1 = InPlaceCharArraySpaceOnly (input1); 
    output2 = InPlaceCharArraySpaceOnly (input2); 
    sw.Stop(); 
    Console.WriteLine("InPlaceCharArraySpaceOnly : " + (sw.ElapsedTicks - baseVal)); 
    Console.WriteLine(" Trial1:(spaces only) " + (output1 == correctOutput1 ? "PASS " : "FAIL ")); 
    Console.WriteLine(" Trial2:(spaces+tabs) " + (output2 == correctOutput2 ? "PASS " : "FAIL ")); 

    // InPlace Replace by Felipe R. Machado and slightly modified by Ryan for multi-space removal (http://www.codeproject.com/Articles/1014073/Fastest-method-to-remove-all-whitespace-from-Strin) 
    output1 = InPlaceCharArray(warmup); 
    sw.Restart(); 
    output1 = InPlaceCharArray(input1); 
    output2 = InPlaceCharArray(input2); 
    sw.Stop(); 
    Console.WriteLine("InPlaceCharArray: " + (sw.ElapsedTicks - baseVal)); 
    Console.WriteLine(" Trial1:(spaces only) " + (output1 == correctOutput1 ? "PASS " : "FAIL ")); 
    Console.WriteLine(" Trial2:(spaces+tabs) " + (output2 == correctOutput2 ? "PASS " : "FAIL ")); 

    //Regex with non-compile Tim Hoolihan (https://stackoverflow.com/a/1279874/2352507) 
    string cleanedString = 
    output1 = Regex.Replace(warmup, @"\s+", " "); 
    sw.Restart(); 
    output1 = Regex.Replace(input1, @"\s+", " "); 
    output2 = Regex.Replace(input2, @"\s+", " "); 
    sw.Stop(); 
    Console.WriteLine("Regex by Tim Hoolihan: " + (sw.ElapsedTicks - baseVal)); 
    Console.WriteLine(" Trial1:(spaces only) " + (output1 == correctOutput1 ? "PASS " : "FAIL ")); 
    Console.WriteLine(" Trial2:(spaces+tabs) " + (output2 == correctOutput2 ? "PASS " : "FAIL ")); 

    //Regex with compile by Jon Skeet (https://stackoverflow.com/a/1280227/2352507) 
    output1 = MultipleSpaces.Replace(warmup, " "); 
    sw.Restart(); 
    output1 = MultipleSpaces.Replace(input1, " "); 
    output2 = MultipleSpaces.Replace(input2, " "); 
    sw.Stop(); 
    Console.WriteLine("Regex with compile by Jon Skeet: " + (sw.ElapsedTicks - baseVal)); 
    Console.WriteLine(" Trial1:(spaces only) " + (output1 == correctOutput1 ? "PASS " : "FAIL ")); 
    Console.WriteLine(" Trial2:(spaces+tabs) " + (output2 == correctOutput2 ? "PASS " : "FAIL ")); 

    //Split And Join by Jon Skeet (https://stackoverflow.com/a/1280227/2352507) 
    output1 = SplitAndJoinOnSpace(warmup); 
    sw.Restart(); 
    output1 = SplitAndJoinOnSpace(input1); 
    output2 = SplitAndJoinOnSpace(input2); 
    sw.Stop(); 
    Console.WriteLine("Split And Join by Jon Skeet: " + (sw.ElapsedTicks - baseVal)); 
    Console.WriteLine(" Trial1:(spaces only) " + (output1 == correctOutput1 ? "PASS " : "FAIL ")); 
    Console.WriteLine(" Trial2:(spaces+tabs) " + (output2 == correctOutput2 ? "PASS " : "FAIL ")); 

    //Regex by Brandon (https://stackoverflow.com/a/1279878/2352507 
    output1 = Regex.Replace(warmup, @"\s{2,}", " "); 
    sw.Restart(); 
    output1 = Regex.Replace(input1, @"\s{2,}", " "); 
    output2 = Regex.Replace(input2, @"\s{2,}", " "); 
    sw.Stop(); 
    Console.WriteLine("Regex by Brandon: " + (sw.ElapsedTicks - baseVal)); 
    Console.WriteLine(" Trial1:(spaces only) " + (output1 == correctOutput1 ? "PASS " : "FAIL ")); 
    Console.WriteLine(" Trial2:(spaces+tabs) " + (output2 == correctOutput2 ? "PASS " : "FAIL ")); 

    //StringBuilder by user214147 (https://stackoverflow.com/a/2156660/2352507 
    output1 = user214147(warmup); 
    sw.Restart(); 
    output1 = user214147(input1); 
    output2 = user214147(input2); 
    sw.Stop(); 
    Console.WriteLine("StringBuilder by user214147: " + (sw.ElapsedTicks - baseVal)); 
    Console.WriteLine(" Trial1:(spaces only) " + (output1 == correctOutput1 ? "PASS " : "FAIL ")); 
    Console.WriteLine(" Trial2:(spaces+tabs) " + (output2 == correctOutput2 ? "PASS " : "FAIL ")); 

    //StringBuilder by fubo (https://stackoverflow.com/a/27502353/2352507 
    output1 = fubo(warmup); 
    sw.Restart(); 
    output1 = fubo(input1); 
    output2 = fubo(input2); 
    sw.Stop(); 
    Console.WriteLine("StringBuilder by fubo: " + (sw.ElapsedTicks - baseVal)); 
    Console.WriteLine(" Trial1:(spaces only) " + (output1 == correctOutput1 ? "PASS " : "FAIL ")); 
    Console.WriteLine(" Trial2:(spaces+tabs) " + (output2 == correctOutput2 ? "PASS " : "FAIL ")); 


    //StringBuilder by David S 2013 (https://stackoverflow.com/a/16035044/2352507) 
    output1 = SingleSpacedTrim(warmup); 
    sw.Restart(); 
    output1 = SingleSpacedTrim(input1); 
    output2 = SingleSpacedTrim(input2); 
    sw.Stop(); 
    Console.WriteLine("StringBuilder(SingleSpacedTrim) by David S: " + (sw.ElapsedTicks - baseVal)); 
    Console.WriteLine(" Trial1:(spaces only) " + (output1 == correctOutput1 ? "PASS " : "FAIL ")); 
    Console.WriteLine(" Trial2:(spaces+tabs) " + (output2 == correctOutput2 ? "PASS " : "FAIL ")); 
} 

// InPlace Replace by Felipe Machado and slightly modified by Ryan for multi-space removal (http://www.codeproject.com/Articles/1014073/Fastest-method-to-remove-all-whitespace-from-Strin) 
static string InPlaceCharArray(string str) 
{ 
    var len = str.Length; 
    var src = str.ToCharArray(); 
    int dstIdx = 0; 
    bool lastWasWS = false; 
    for (int i = 0; i < len; i++) 
    { 
     var ch = src[i]; 
     if (src[i] == '\u0020') 
     { 
      if (lastWasWS == false) 
      { 
       src[dstIdx++] = ch; 
       lastWasWS = true; 
      } 
     } 
     else 
     { 
      lastWasWS = false; 
      src[dstIdx++] = ch; 
     } 
    } 
    return new string(src, 0, dstIdx); 
} 

// InPlace Replace by Felipe R. Machado but modified by Ryan for multi-space removal (http://www.codeproject.com/Articles/1014073/Fastest-method-to-remove-all-whitespace-from-Strin) 
static string InPlaceCharArraySpaceOnly (string str) 
{ 
    var len = str.Length; 
    var src = str.ToCharArray(); 
    int dstIdx = 0; 
    bool lastWasWS = false; //Added line 
    for (int i = 0; i < len; i++) 
    { 
     var ch = src[i]; 
     switch (ch) 
     { 
      case '\u0020': //SPACE 
      case '\u00A0': //NO-BREAK SPACE 
      case '\u1680': //OGHAM SPACE MARK 
      case '\u2000': // EN QUAD 
      case '\u2001': //EM QUAD 
      case '\u2002': //EN SPACE 
      case '\u2003': //EM SPACE 
      case '\u2004': //THREE-PER-EM SPACE 
      case '\u2005': //FOUR-PER-EM SPACE 
      case '\u2006': //SIX-PER-EM SPACE 
      case '\u2007': //FIGURE SPACE 
      case '\u2008': //PUNCTUATION SPACE 
      case '\u2009': //THIN SPACE 
      case '\u200A': //HAIR SPACE 
      case '\u202F': //NARROW NO-BREAK SPACE 
      case '\u205F': //MEDIUM MATHEMATICAL SPACE 
      case '\u3000': //IDEOGRAPHIC SPACE 
      case '\u2028': //LINE SEPARATOR 
      case '\u2029': //PARAGRAPH SEPARATOR 
      case '\u0009': //[ASCII Tab] 
      case '\u000A': //[ASCII Line Feed] 
      case '\u000B': //[ASCII Vertical Tab] 
      case '\u000C': //[ASCII Form Feed] 
      case '\u000D': //[ASCII Carriage Return] 
      case '\u0085': //NEXT LINE 
       if (lastWasWS == false) //Added line 
       { 
        src[dstIdx++] = ch; //Added line 
        lastWasWS = true; //Added line 
       } 
      continue; 
      default: 
       lastWasWS = false; //Added line 
       src[dstIdx++] = ch; 
       break; 
     } 
    } 
    return new string(src, 0, dstIdx); 
} 

static readonly Regex MultipleSpaces = 
    new Regex(@" {2,}", RegexOptions.Compiled); 

//Split And Join by Jon Skeet (https://stackoverflow.com/a/1280227/2352507) 
static string SplitAndJoinOnSpace(string input) 
{ 
    string[] split = input.Split(new char[] { ' '}, StringSplitOptions.RemoveEmptyEntries); 
    return string.Join(" ", split); 
} 

//StringBuilder by user214147 (https://stackoverflow.com/a/2156660/2352507 
public static string user214147(string S) 
{ 
    string s = S.Trim(); 
    bool iswhite = false; 
    int iwhite; 
    int sLength = s.Length; 
    StringBuilder sb = new StringBuilder(sLength); 
    foreach (char c in s.ToCharArray()) 
    { 
     if (Char.IsWhiteSpace(c)) 
     { 
      if (iswhite) 
      { 
       //Continuing whitespace ignore it. 
       continue; 
      } 
      else 
      { 
       //New WhiteSpace 

       //Replace whitespace with a single space. 
       sb.Append(" "); 
       //Set iswhite to True and any following whitespace will be ignored 
       iswhite = true; 
      } 
     } 
     else 
     { 
      sb.Append(c.ToString()); 
      //reset iswhitespace to false 
      iswhite = false; 
     } 
    } 
    return sb.ToString(); 
} 

//StringBuilder by fubo (https://stackoverflow.com/a/27502353/2352507 
public static string fubo(this string Value) 
{ 
    StringBuilder sbOut = new StringBuilder(); 
    if (!string.IsNullOrEmpty(Value)) 
    { 
     bool IsWhiteSpace = false; 
     for (int i = 0; i < Value.Length; i++) 
     { 
      if (char.IsWhiteSpace(Value[i])) //Comparison with WhiteSpace 
      { 
       if (!IsWhiteSpace) //Comparison with previous Char 
       { 
        sbOut.Append(Value[i]); 
        IsWhiteSpace = true; 
       } 
      } 
      else 
      { 
       IsWhiteSpace = false; 
       sbOut.Append(Value[i]); 
      } 
     } 
    } 
    return sbOut.ToString(); 
} 

//David S. 2013 (https://stackoverflow.com/a/16035044/2352507) 
public static String SingleSpacedTrim(String inString) 
{ 
    StringBuilder sb = new StringBuilder(); 
    Boolean inBlanks = false; 
    foreach (Char c in inString) 
    { 
     switch (c) 
     { 
      case '\r': 
      case '\n': 
      case '\t': 
      case ' ': 
       if (!inBlanks) 
       { 
        inBlanks = true; 
        sb.Append(' '); 
       } 
       continue; 
      default: 
       inBlanks = false; 
       sb.Append(c); 
       break; 
     } 
    } 
    return sb.ToString().Trim(); 
} 

/// <summary> 
/// We want to run this item with max priory to lower the odds of 
/// the OS from doing program context switches in the middle of our code. 
/// source:https://stackoverflow.com/a/16157458 
/// </summary> 
/// <returns>random seed</returns> 
private static long ConfigProgramForBenchmarking() 
{ 
    //prevent the JIT Compiler from optimizing Fkt calls away 
    long seed = Environment.TickCount; 
    //use the second Core/Processor for the test 
    Process.GetCurrentProcess().ProcessorAffinity = new IntPtr(2); 
    //prevent "Normal" Processes from interrupting Threads 
    Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High; 
    //prevent "Normal" Threads from interrupting this thread 
    Thread.CurrentThread.Priority = ThreadPriority.Highest; 
    return seed; 
} 

}

Las notas de referencia: Modo de disparo, sin depurador adjunto, procesador i7, promedio de 4 carreras, solo cadenas cortas probadas

Cuestiones relacionadas