将string拆分为行的最佳方法

如何将多行string分割成多行?

我知道这种方式

var result = input.Split("\n\r".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 

看起来有点丑,失去了空虚的线条。 有更好的解决scheme吗?

  • 如果它看起来很丑,只要删除不必要的ToCharArray调用即可。

  • 如果你想分割\n\r ,你有两个select:

    • 使用数组文字 – 但是这会给你空行的Windows风格的行尾\r\n

       var result = text.Split(new [] { '\r', '\n' }); 
    • 使用正则expression式,如Bart所示:

       var result = Regex.Split(text, "\r\n|\r|\n"); 
  • 如果你想保留空行,为什么你明确告诉C#把它们扔掉? ( StringSplitOptions参数) – 改为使用StringSplitOptions.None

 using (StringReader sr = new StringReader(text)) { string line; while ((line = sr.ReadLine()) != null) { // do something } } 

你可以使用Regex.Split:

 string[] tokens = Regex.Split(input, @"\r?\n|\r"); 

编辑:添加|\r帐户(旧)Mac行终止符。

更新: 在这里看到更好的解决scheme。


这工作很好,比正则expression式更快:

 input.Split(new[] {"\r\n", "\r", "\n"}, StringSplitOptions.None) 

在数组中首先要有"\r\n" ,这样才能将其作为一个换行符。 以上给出了这些正则expression式解决scheme的结果:

 Regex.Split(input, "\r\n|\r|\n") Regex.Split(input, "\r?\n|\r") 

除了正则expression式大约慢了10倍。 这是我的testing:

 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") ); 

输出:

00:00:03.8527616

00:00:31.8017726

00:00:32.5557128

这里是扩展方法:

 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); } } 

用法:

 input.GetLines() // keeps empty lines input.GetLines(true) // removes empty lines 

如果你想保留空行,只需删除StringSplitOptions。

 var result = input.Split(System.Environment.NewLine.ToCharArray()); 

我还有其他的答案,但是根据杰克的回答 ,这个答案显着(1000倍以上)。

 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; } } } } 

用法:

 input.GetLines() // keeps empty lines input.GetLines(true) // removes empty lines 

testing:

 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() ); 

输出:

00:00:03.9603894

00:00:00.0029996

稍微扭曲,但是要做一个迭代器块:

 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); } 

然后你可以打电话给:

 var result = input.Lines().ToArray(); 
  char[] archDelim = new char[] { '\r', '\n' }; words = asset.text.Split(archDelim, StringSplitOptions.RemoveEmptyEntries); 
  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(); }