una - string c# ejemplos
¿La forma más fácil de dividir una cadena en nuevas líneas en.NET? (15)
Necesito dividir una cadena en nuevas líneas en .NET y la única forma 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?
¿Qué pasa con el uso de un StringReader
?
using (System.IO.StringReader reader = new System.IO.StringReader(input)) {
string line = reader.ReadLine();
}
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
Intenta dividirse primero en la nueva línea de la plataforma local, y luego recae en cada nueva línea 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 convierta en un método de extensión.
Aquí le indicamos cómo unir las líneas de respaldo, por si acaso:
Private Shared Function JoinLines(lines As IEnumerable(Of String)) As String
Return String.Join(Environment.NewLine, lines)
End Function
Basado en 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);
}
Bueno, en realidad la división 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]);
}
Deberías poder dividir tu cadena con bastante facilidad, así:
aString.Split(Environment.NewLine.ToCharArray());
Intente evitar el uso de la cadena. Participe en una solución general, porque usará más memoria en todos los lugares donde utilice la función: la cadena original y la copia dividida, ambas en la memoria. Confíe en que esto puede ser un gran problema cuando comience a escalar: ejecute una aplicación de procesamiento de lotes de 32 bits que procesa documentos de 100 MB, y caga en ocho subprocesos simultáneos. No es que haya estado allí antes ...
En su lugar, utilice un iterador como este;
public static IEnumerable<string> 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 de memoria más eficiente alrededor de sus datos;
foreach(var line in document.SplitToLines())
{
// one line at a time...
}
Por supuesto, si lo quiere todo en la memoria, puede hacer esto;
var allTheLines = document.SplitToLines.ToArray();
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);
}
No sabía sobre Environment.Newline, pero creo que esta es una muy buena solución.
Mi intento 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 todavía presente (por ejemplo, cuando está en Windows pero dividiendo una cadena con caracteres de nueva línea de OS x). Aunque probablemente no sea el método más rápido.
EDITAR:
Como los comentarios señalaron correctamente, esto también elimina cualquier espacio en blanco al comienzo de la línea o antes del nuevo salto de línea. Si necesita conservar ese espacio en blanco, use una de las otras opciones.
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 espaciado en el texto:
string[] lines = theText.Split(
new[] { "/r/n", "/r", "/n" },
StringSplitOptions.None
);
Para una variable de cadena s
:
s.Split(new string[]{Environment.NewLine},StringSplitOptions.None)
Esto utiliza la definición de fin de línea de su entorno. En Windows, los finales 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 recombinan las líneas con String.Join
, esto es igual a su 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:
- Use
StringSplitOptions.RemoveEmptyEntries
, porque esto 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 nueva línea.
Regex también es una opción:
private string[] SplitStringByLineFeed(string inpString)
{
string[] locResult = Regex.Split(inpString, "[/r/n]+");
return locResult;
}
Respuesta tonta: escriba en un archivo temporal para que pueda 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);
Solo pensé que agregaría mis dos bits porque las otras soluciones en esta pregunta no entran en la clasificación de código reutilizable y no son convenientes. El siguiente bloque de código extiende 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()
de 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 parámetro delimitador.
Comentario: Sería bueno si Microsoft implementara esta sobrecarga.
// using System.IO;
string textToSplit;
if(textToSplit!=null)
{
List<string> lines = new List<string>();
using (StringReader reader = new StringReader(textToSplit))
{
for (string line = reader.ReadLine(); line != null;line = reader.ReadLine())
{
lines.Add(line);
}
}
}
string[] lines = text.Split(
Environment.NewLine.ToCharArray(),
StringSplitOptions.RemoveEmptyStrings);
La opción RemoveEmptyStrings se asegurará de que no tenga entradas vacías debido a que / n sigue a / r
(Edite para reflejar los comentarios :) Tenga en cuenta que también descartará las líneas vacías genuinas en el texto. Esto suele ser lo que quiero, pero puede que no sea su requisito.