La mejor manera de dividir la cadena en líneas
¿Cómo se divide la cadena de varias líneas en líneas?
Sé de esta manera
var result = input.Split("\n\r".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
Se ve un poco feo y pierde líneas vacías. Hay una solución mejor?
9 answers
Si se ve feo, simplemente elimine la llamada innecesaria
ToCharArray
.-
Si desea dividir por
\n
o\r
, tienes dos opciones:-
Use un array literal-pero esto le dará líneas vacías para las terminaciones de línea de estilo Windows
\r\n
:var result = text.Split(new [] { '\r', '\n' });
-
Use una expresión regular, como indica Bart:
var result = Regex.Split(text, "\r\n|\r|\n");
-
Si desea conservar líneas vacías, ¿por qué le dice explícitamente a C# que las lance ¿lejos? (
StringSplitOptions
parámetro) - utiliceStringSplitOptions.None
en su lugar.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-03 08:42:59
using (StringReader sr = new StringReader(text)) {
string line;
while ((line = sr.ReadLine()) != null) {
// do something
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-20 16:33:35
Puedes usar expresiones regulares.División:
string[] tokens = Regex.Split(input, @"\r?\n|\r");
Editar: se agregó |\r
para tener en cuenta los terminadores de línea Mac (más antiguos).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-26 16:09:37
Actualizar: Ver aquí para una solución alternativa/asincrónica.
Esto funciona muy bien y es más rápido que Regex:
input.Split(new[] {"\r\n", "\r", "\n"}, StringSplitOptions.None)
Es importante tener "\r\n"
primero en la matriz para que se tome como un salto de línea. Lo anterior da los mismos resultados que cualquiera de estas soluciones Regex:
Regex.Split(input, "\r\n|\r|\n")
Regex.Split(input, "\r?\n|\r")
Excepto que la expresión regular resulta ser aproximadamente 10 veces más lenta. Aquí está mi prueba:
Action<Action> measure = (Action func) => {
var start = DateTime.Now;
for (int i = 0; i < 100000; i++) {
func();
}
var duration = DateTime.Now - start;
Console.WriteLine(duration);
};
var input = "";
for (int i = 0; i < 100; i++)
{
input += "1 \r2\r\n3\n4\n\r5 \r\n\r\n 6\r7\r 8\r\n";
}
measure(() =>
input.Split(new[] {"\r\n", "\r", "\n"}, StringSplitOptions.None)
);
measure(() =>
Regex.Split(input, "\r\n|\r|\n")
);
measure(() =>
Regex.Split(input, "\r?\n|\r")
);
Salida:
00:00:03.8527616
00:00:31.8017726
00:00:32.5557128
Y aquí está el Método de extensión :
public static class StringExtensionMethods
{
public static IEnumerable<string> GetLines(this string str, bool removeEmptyLines = false)
{
return str.Split(new[] { "\r\n", "\r", "\n" },
removeEmptyLines ? StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None);
}
}
Uso:
input.GetLines() // keeps empty lines
input.GetLines(true) // removes empty lines
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-01 23:45:30
Si desea mantener líneas vacías, simplemente elimine las StringSplitOptions.
var result = input.Split(System.Environment.NewLine.ToCharArray());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-02 07:57:23
Tenía esta otra respuesta pero esta, basada en la respuesta de Jack , es significativamente más rápido podría ser preferido ya que funciona asincrónicamente, aunque ligeramente más lento.
public static class StringExtensionMethods
{
public static IEnumerable<string> GetLines(this string str, bool removeEmptyLines = false)
{
using (var sr = new StringReader(str))
{
string line;
while ((line = sr.ReadLine()) != null)
{
if (removeEmptyLines && String.IsNullOrWhiteSpace(line))
{
continue;
}
yield return line;
}
}
}
}
Uso:
input.GetLines() // keeps empty lines
input.GetLines(true) // removes empty lines
Prueba:
Action<Action> measure = (Action func) =>
{
var start = DateTime.Now;
for (int i = 0; i < 100000; i++)
{
func();
}
var duration = DateTime.Now - start;
Console.WriteLine(duration);
};
var input = "";
for (int i = 0; i < 100; i++)
{
input += "1 \r2\r\n3\n4\n\r5 \r\n\r\n 6\r7\r 8\r\n";
}
measure(() =>
input.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None)
);
measure(() =>
input.GetLines()
);
measure(() =>
input.GetLines().ToList()
);
Salida:
00:00:03.9603894
00:00:00.0029996
00:00:04.8221971
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-01 23:59:33
Ligeramente retorcido, pero un bloque iterador para hacerlo:
public static IEnumerable<string> Lines(this string Text)
{
int cIndex = 0;
int nIndex;
while ((nIndex = Text.IndexOf(Environment.NewLine, cIndex + 1)) != -1)
{
int sIndex = (cIndex == 0 ? 0 : cIndex + 1);
yield return Text.Substring(sIndex, nIndex - sIndex);
cIndex = nIndex;
}
yield return Text.Substring(cIndex + 1);
}
Puedes llamar a:
var result = input.Lines().ToArray();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-02 08:08:27
char[] archDelim = new char[] { '\r', '\n' };
words = asset.text.Split(archDelim, StringSplitOptions.RemoveEmptyEntries);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-11 05:58:21
private string[] GetLines(string text)
{
List<string> lines = new List<string>();
using (MemoryStream ms = new MemoryStream())
{
StreamWriter sw = new StreamWriter(ms);
sw.Write(text);
sw.Flush();
ms.Position = 0;
string line;
using (StreamReader sr = new StreamReader(ms))
{
while ((line = sr.ReadLine()) != null)
{
lines.Add(line);
}
}
sw.Close();
}
return lines.ToArray();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-06 00:55:53