2012-06-25 15 views
30

Estoy eliminando el texto de una cadena y qué reemplazar cada línea con una línea en blanco.¿Cómo contar las líneas en una cadena?

Algunos antecedentes: estoy escribiendo una función que compara dos cadenas comparar. Todo funciona bien y se muestran dos navegadores web separados. Cuando intento desplazarme hacia abajo en mis navegadores las cadenas tienen diferentes longitudes, quiero reemplazar el texto que estoy eliminando con una línea en blanco para que mis cadenas tengan la misma longitud.

En el siguiente código miro para contar el número de líneas aDiff.Text tiene

Aquí está mi código:

public string diff_prettyHtmlShowInserts(List<Diff> diffs) 
    { 
     StringBuilder html = new StringBuilder(); 

     foreach (Diff aDiff in diffs) 
     { 
      string text = aDiff.text.Replace("&", "&amp;").Replace("<", "&lt;") 
       .Replace(">", "&gt;").Replace("\n", "<br>"); //&para; 
      switch (aDiff.operation) 
      { 

       case Operation.DELETE:        
        //foreach('\n' in aDiff.text) 
        // { 
        //  html.Append("\n"); // Would like to replace each line with a blankline 
        // } 
        break; 
       case Operation.EQUAL: 
        html.Append("<span>").Append(text).Append("</span>"); 
        break; 
       case Operation.INSERT: 
        html.Append("<ins style=\"background:#e6ffe6;\">").Append(text) 
         .Append("</ins>"); 
        break; 
      } 
     } 
     return html.ToString(); 
    } 
+0

Anexar
.. –

+0

Esto funciona, pero tengo que tener una nueva línea para cada una de las viejas líneas que sólo hace una nueva línea para toda una cadena que podría ser de 8 líneas – Pomster

Respuesta

57
  1. int numLines = aDiff.text.Length - aDiff.text.Replace(Environment.NewLine, string.Empty).Length;

  2. int numLines = aDiff.text.Split('\n').Length;

tanto le dará el número de líneas en el texto ...

+0

Gracias me permiten comprobar hacia fuera: D – Pomster

+0

La mejor coincidencia de método sobrecargado para 'string.Split (params char [])' tiene algunos argumentos inválidos \t es el error que recibí – Pomster

+1

Puede usar '\ n' allí en lugar de' Environment.NewLine' ... – poncha

6

ineficiente, pero aún así:

var newLineCount = aDiff.Text.Split('\n').Length -1; 
+0

¡ni siquiera compila! var newLineCount = aDiff.Text.Split (nueva cadena [] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries) .Length; – ilmatte

+0

Simplemente use el carácter de nueva línea '\ n' – nunespascal

+0

Disculpe, tiene razón, compila. Sin embargo, Environment.NewLine se traduce al carácter de nueva línea derecha para la plataforma en la que se ejecuta la aplicación: http://msdn.microsoft.com/it-it/library/system.environment.newline.aspx – ilmatte

2
int newLineLen = Environment.NewLine.Length; 
int numLines = aDiff.text.Length - aDiff.text.Replace(Environment.NewLine, string.Empty).Length; 
if (newLineLen != 0) 
    { 
    numLines /= newLineLen; 
    numLines++; 
    } 

ligeramente más robusto, lo que representa la primera línea que no tiene un salto de línea.

+0

¿Por qué (cuándo) ' Environment.NewLine.Length' ¿devuelve cero? Cita de https://msdn.microsoft.com/en-us/library/system.environment.newline(v=vs.110).aspx: * Una cadena que contiene "\ r \ n" para plataformas que no son Unix, o una cadena que contiene "\ n" para plataformas Unix. * – poncha

+0

No tengo idea de por qué sería una longitud de cero. Pero cuando divido por algo que no soy absolutamente 100% no será cero, entonces lo verifico de todos modos. Pero sí, tienes razón, tal como está en las plataformas compatibles actuales, no debería ser cero. –

2

Para facilitar las cosas, i poner la solución de poncha en un método de extensión agradable, por lo que puede usarlo simplemente como esto:

int numLines = aDiff.text.LineCount(); 

El código:

/// <summary> 
/// Extension class for strings. 
/// </summary> 
public static class StringExtensions 
{ 
    /// <summary> 
    /// Get the nummer of lines in the string. 
    /// </summary> 
    /// <returns>Nummer of lines</returns> 
    public static int LineCount(this string str) 
    { 
     return str.Split('\n').Length; 
    } 
} 

divertirse. ..

2

Hice un montón de pruebas de rendimiento de diferentes métodos (Split, Replace, para loop over chars, Linq.Count) y el ganador fue el método Replace (el método Split fue sligh mucho más rápido cuando las cadenas son menos de 2 KB, pero no mucho).

Pero hay 2 errores en la respuesta aceptada. Un error es cuando la última línea no termina con una nueva línea, no contará la última línea. El otro error es que si está leyendo un archivo con terminaciones de línea UNIX en Windows no contará ninguna línea ya que Environment.Newline es \r\n y no existirá (siempre puede usar \n ya que es el último carácter de una línea terminando para UNIX y Windows).

Así que aquí hay un método de extensión simple ...

public static int CountLines(this string text) 
{ 
    int count = 0; 
    if (!string.IsNullOrEmpty(text)) 
    { 
     count = text.Length - text.Replace("\n", string.Empty).Length; 

     // if the last char of the string is not a newline, make sure to count that line too 
     if (text[text.Length - 1] != '\n') 
     { 
      ++count; 
     } 
    } 

    return count; 
} 
3

Una variante que no Alocate nuevas cadenas o matriz de cadenas

private static int CountLines(string str) 
{ 
    if (str == null) 
     throw new ArgumentNullException("str"); 
    if (str == string.Empty) 
     return 0; 
    int index = -1; 
    int count = 0; 
    while (-1 != (index = str.IndexOf(Environment.NewLine, index + 1))) 
     count++; 

    return count + 1; 
} 
0

También puede utilizar LINQ para contar las apariciones de líneas, así:

int numLines = aDiff.Count(c => c.Equals('\n')) + 1; 

tarde, pero ofrece una alternativa a otras respuestas. ?

Cuestiones relacionadas