La forma más fácil de dividir una cadena en nuevas líneas en .NET?

Necesito dividir una cadena en nuevas líneas en .NET y la única manera que conozco de dividir cadenas es con el método Split . Sin embargo, eso no me permitirá dividir (fácilmente) en una nueva línea, entonces, ¿cuál es la mejor manera de hacerlo?

Para dividir en una cadena, necesita usar la sobrecarga que toma una matriz de cadenas:

string[] lines = theText.Split( new[] { Environment.NewLine }, StringSplitOptions.None ); 

Editar:
Si desea manejar diferentes tipos de saltos de línea en un texto, puede usar la capacidad de hacer coincidir más de una cadena. Esto se dividirá correctamente en cualquier tipo de salto de línea, y conservará las líneas vacías y el espacio en el texto:

 string[] lines = theText.Split( new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None ); 

¿Qué hay de usar un StringReader ?

 using (System.IO.StringReader reader = new System.IO.StringReader(input)) { string line = reader.ReadLine(); } 

Deberías poder dividir tu cadena bastante fácilmente, así:

 aString.Split(Environment.NewLine.ToCharArray()); 

Según la respuesta de Guffa, en una clase de extensión, use:

 public static string[] Lines(this string source) { return source.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None); } 

Intente evitar el uso de cadenas. Separe para obtener una solución general, ya que usará más memoria en todos los lugares donde use la función: la cadena original y la copia dividida, ambas en la memoria. Confíe en mí que este puede ser un gran problema cuando empiece a escalar: ejecute una aplicación de procesamiento por lotes de 32 bits que procesa documentos de 100 MB, y obtendrá ocho subprocesos simultáneos. No es que haya estado allí antes …

En cambio, use un iterador como este;

  public static IEnumerable SplitToLines(this string input) { if (input == null) { yield break; } using (System.IO.StringReader reader = new System.IO.StringReader(input)) { string line; while( (line = reader.ReadLine()) != null) { yield return line; } } } 

Esto le permitirá hacer un bucle más eficiente de la memoria en torno a sus datos;

 foreach(var line in document.SplitToLines()) { // one line at a time... } 

Por supuesto, si lo quieres todo en la memoria, puedes hacer esto;

 var allTheLines = document.SplitToLines.ToArray(); 

Para una variable de cadena s :

 s.Split(new string[]{Environment.NewLine},StringSplitOptions.None) 

Esto usa la definición de terminaciones de línea de su entorno. En Windows, las terminaciones de línea son CR-LF (retorno de carro, avance de línea) o en los caracteres de escape de C # \r\n .

Esta es una solución confiable, porque si recombinas las líneas con String.Join , esto es igual a tu cadena original:

 var lines = s.Split(new string[]{Environment.NewLine},StringSplitOptions.None); var reconstituted = String.Join(Environment.NewLine,lines); Debug.Assert(s==reconstituted); 

Qué no hacer:

  • Utilice StringSplitOptions.RemoveEmptyEntries porque romperá el marcado, como Markdown, donde las líneas vacías tienen un propósito sintáctico.
  • Dividir en separador new char[]{Environment.NewLine} , porque en Windows esto creará un elemento de cadena vacío para cada línea nueva.

Regex también es una opción:

  private string[] SplitStringByLineFeed(string inpString) { string[] locResult = Regex.Split(inpString, "[\r\n]+"); return locResult; } 

Solo pensé en agregar mis dos bits porque las otras soluciones en esta pregunta no entran en la clasificación del código reutilizable y no son convenientes. El siguiente bloque de código amplía el objeto de string para que esté disponible como un método natural cuando se trabaja con cadenas.

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; using System.Collections.ObjectModel; namespace System { public static class StringExtensions { public static string[] Split(this string s, string delimiter, StringSplitOptions options = StringSplitOptions.None) { return s.Split(new string[] { delimiter }, options); } } } 

Ahora puede usar la función .Split() desde cualquier cadena de la siguiente manera:

 string[] result; // pass a string, and the delimiter result = string.Split("My simple string", " "); // split an existing string by delimiter only string foo = "my - string - i - want - split"; result = foo.Split("-"); // you can even pass the split options param. when omitted it is // set to StringSplitOptions.None result = foo.Split("-", StringSplitOptions.RemoveEmptyEntries); 

Para dividir en un carácter de nueva línea, simplemente pase "\n" o "\r\n" como el parámetro del delimitador.

Comentario: Sería bueno si Microsoft implementara esta sobrecarga.

Actualmente estoy usando esta función (basada en otras respuestas) en VB.NET:

 Private Shared Function SplitLines(text As String) As String() Return text.Split({Environment.NewLine, vbCrLf, vbLf}, StringSplitOptions.None) End Function 

Primero intenta dividirse en la nueva línea local de la plataforma, y ​​luego vuelve a caer en cada línea nueva posible.

Solo he necesitado esto dentro de una clase hasta ahora. Si eso cambia, probablemente lo haga Public y lo mueva a una clase de utilidad, y tal vez incluso lo haga un método de extensión.

A continuación, le indicamos cómo unir las líneas de respaldo, para una buena medida:

 Private Shared Function JoinLines(lines As IEnumerable(Of String)) As String Return String.Join(Environment.NewLine, lines) End Function 

Bueno, en realidad, dividir debería hacer:

 //Constructing string... StringBuilder sb = new StringBuilder(); sb.AppendLine("first line"); sb.AppendLine("second line"); sb.AppendLine("third line"); string s = sb.ToString(); Console.WriteLine(s); //Splitting multiline string into separate lines string[] splitted = s.Split(new string[] {System.Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries); // Output (separate lines) for( int i = 0; i < splitted.Count(); i++ ) { Console.WriteLine("{0}: {1}", i, splitted[i]); } 
 string[] lines = text.Split( Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyStrings); 

La opción RemoveEmptyStrings se asegurará de que no tenga entradas vacías debido a \ n después de una \ r

(Editar para reflejar los comentarios 🙂 Tenga en cuenta que también descartará las líneas vacías genuinas en el texto. Esto es generalmente lo que quiero, pero puede que no sea su requisito.

No sabía acerca de Environment.Newline, pero creo que esta es una muy buena solución.

Mi bash hubiera sido:

  string str = "Test Me\r\nTest Me\nTest Me"; var splitted = str.Split('\n').Select(s => s.Trim()).ToArray(); 

El .Trim adicional elimina cualquier \ r o \ n que pueda estar presente (por ejemplo, cuando está en Windows pero cortando una cadena con os x caracteres de nueva línea). Probablemente no sea el método más rápido.

EDITAR:

Como los comentarios indicaron correctamente, esto también elimina cualquier espacio en blanco al comienzo de la línea o antes de la nueva línea. Si necesita conservar ese espacio en blanco, use una de las otras opciones.

Silly answer: escribe en un archivo temporal para que puedas usar el venerable File.ReadLines

 var s = "Hello\r\nWorld"; var path = Path.GetTempFileName(); using (var writer = new StreamWriter(path)) { writer.Write(s); } var lines = File.ReadLines(path); 
 // using System.IO; string textToSplit; if(textToSplit!=null) { List lines = new List(); using (StringReader reader = new StringReader(textToSplit)) { for (string line = reader.ReadLine(); line != null;line = reader.ReadLine()) { lines.Add(line); } } } 

Muy fácil, en realidad.

VB.NET:

 Private Function SplitOnNewLine(input as String) As String Return input.Split(Environment.NewLine) End Function 

DO#:

 string splitOnNewLine(string input) { return input.split(environment.newline); }