2010-07-08 16 views
5

Tengo un objeto Stringbuilder que se ha llenado desde un archivo de texto. ¿Cómo puedo verificar el objeto StringBuilder para eliminar líneas consecutivas "en blanco"?Eliminación de filas en blanco consecutivas de StringBuilder

es decir

Line 1: This is my text 
Line 2: 
Line 3: Another line after the 1st blank one 
Line 4: 
Line 5: 
Line 6: Next line after 2 blank lines 

(números de línea dada como referencia solamente)

la línea en blanco en la línea 2 está muy bien, pero me gustaría para eliminar la línea en blanco duplicado, en la línea 5, y así en.

Si por argumento sake la Línea 6 también habría sido una línea en blanco, y una Línea 7 tenía un valor, me gustaría eliminar Línea en blanco 5 y Línea en blanco 6, de modo que solo hubiera 1 línea en blanco entre la Línea 3 y Línea 7.

Gracias de antemano.

+0

Simplemente no los adjunte() al StringBuilder cuando lea el archivo. –

+0

Gracias, pero es otro componente que se lee en el archivo de texto que tiene un método .GetStringBuilder(). Lo siento, se olvidó de mencionar eso. – Riaan

Respuesta

3

¿Tiene que tener ya el contenido del archivo en un StringBuilder?

Sería mejor poder leer línea por línea. Algo así como:

private IEnumerable<string> GetLinesFromFile(string fileName) 
{ 
    using (var streamReader = new StreamReader(fileName)) 
    { 
    string line = null; 
    bool previousLineWasBlank = false; 
    while ((line = streamReader.ReadLine()) != null) 
    { 
     if (!previousLineWasBlank && string.IsNullOrEmpty(line)) 
     { 
     yield return line; 
     } 

     previousLineWasBlank = string.IsNullOrEmpty(line); 
    } 
    } 
} 

Ahora se puede leer en el texto (que ha tenido líneas en blanco duplicados eliminados) como esto:

foreach (var line in GetLinesFromFile("myFile.txt")) 
{ 
    Console.WriteLine(line); 
} 

Nota: Sólo estoy ilustrando una técnica aquí. Hay otras consideraciones: p. mi método de iterador mantiene abierto el archivo mientras los consumidores procesan el foreach. Esto es agradable y eficiente desde el punto de vista de la memoria (más que leer en una cadena por ejemplo) ya que solo se trata de una línea a la vez, pero no es ideal para archivos que tardan mucho tiempo en procesarse.

+0

Sí, lo haría, pero es otro componente que se lee en el archivo de texto que tiene un método .GetStringBuilder(). Lo siento, se olvidó de mencionar eso. Lo tendré en cuenta cuando lea en archivos de texto yo mismo. – Riaan

+0

+1 Por usar [email protected], sugiero que ignores/reescribas el otro componente. De las respuestas ingresadas hasta ahora, esta es de lejos la más eficiente y deja la puerta abierta para usar memorias intermedias para archivos más grandes. El enfoque de StringBuilder funcionará mucho más lento que la transmisión. –

+0

@Daniel. De acuerdo. – Riaan

2

StringBuilder es mucho menos flexible cuando se trata de buscar & eliminando. Se usa como un ayudante para acelerar la concatenación ya que "string" + "another string" es una operación muy costosa.

Sugeriría usar .ToString() luego Regex.Replace con una expresión regular compilada con banderas configuradas para permitir multilínea.

es probable que desee un patrón de búsqueda de:

(\n[\w-\n]*\n) 

Y que se sustituya por la cadena vacía.

Consulte Expresso para obtener una excelente herramienta de expresión .NET regular.

+0

Lo intentaré, y gracias por el consejo sobre la herramienta RegEx. – Riaan

3

Probablemente no sea muy eficiente, pero es fácil.

while(sb.ToString().Contains(Environment.NewLine + Environment.NewLine)) 
{ 
    sb = sb.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine); 
} 
+1

"no muy eficiente" es un eufemismo bastante grande. –

+1

@Hans: Bueno, todo es relativo, en un proyecto reciente que reescribí, los desarrolladores anteriores habían utilizado la automatización de Excel para analizar archivos csv (abrir el archivo en Excel, copiar las 32,000 primeras filas * 12 columnas, celda por celda a una matriz multidim en la aplicación C#), tomó aproximadamente 12 minutos cargar el archivo promedio de 300 líneas en la memoria. Entonces, comparativamente, no creo que esto sea demasiado malo :) –

+0

Hmya, * todo * es relativo a eso, supongo. –

Cuestiones relacionadas