Easiest way to split a string on newlines in .NET?
我需要在.NET中将一个字符串拆分为新行,我知道的唯一拆分字符串的方法是使用split方法。然而,这不允许我(很容易)在新行上拆分,那么最好的方法是什么呢?
要对字符串进行拆分,需要使用接受字符串数组的重载:
1 2 3 4 |
编辑:如果要处理文本中不同类型的换行符,可以使用匹配多个字符串的功能。这将在任一类型的换行符上正确拆分,并在文本中保留空行和间距:
1 2 3 4 5 6 7 8 |
使用
1 2 3 | using (System.IO.StringReader reader = new System.IO.StringReader(input)) { string line = reader.ReadLine(); } |
您应该能够很容易地拆分字符串,比如:
1 | aString.Split(Environment.NewLine.ToCharArray()); |
尽量避免使用string.split作为一般的解决方案,因为在使用函数的任何地方都会使用更多的内存——原始字符串和split copy,都在内存中。相信我,当您开始扩展时,这可能是一个非常棘手的问题——运行一个32位的批处理应用程序来处理100MB的文档,然后您将在8个并发线程上死记硬背。不是说我以前去过那里…
相反,使用这样的迭代器;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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; } } } |
这将允许您围绕数据进行更高效的内存循环;
1 2 3 4 | foreach(var line in document.SplitToLines()) { // one line at a time... } |
当然,如果你想要所有的记忆,你可以这样做;
1 | var allTheLines = document.SplitToLines.ToArray(); |
根据Guffa的答案,在扩展类中,使用:
1 2 3 4 5 6 | public static string[] Lines(this string source) { return source.Split(new string[] {" "," " }, StringSplitOptions.None); } |
对于字符串变量
1 |
这将使用环境中的行尾定义。在Windows上,行尾是CR-LF(回车、换行)或C的转义字符
中的行尾。
这是一个可靠的解决方案,因为如果您用
1 2 3 | var lines = s.Split(new string[]{Environment.NewLine},StringSplitOptions.None); var reconstituted = String.Join(Environment.NewLine,lines); Debug.Assert(s==reconstituted); |
不该做什么:
- 使用
StringSplitOptions.RemoveEmptyEntries ,因为这将破坏标记,例如标记,其中空行具有句法目的。 - 在分隔符
new char[]{Environment.NewLine} 上拆分,因为在Windows中,这将为每个新行创建一个空字符串元素。
Regex也是一个选项:
1 2 3 4 5 6 7 | private string[] SplitStringByLineFeed(string inpString) { string[] locResult = Regex.Split(inpString,"[ ]+"); return locResult; } |
我只是想添加我的两个部分,因为这个问题的其他解决方案不属于可重用代码分类,而且不方便。下面的代码块扩展了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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); } } } |
现在可以从以下任意字符串中使用
1 2 3 4 5 6 7 8 9 10 11 12 | 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); |
要在换行字符上拆分,只需将
"
"作为分隔符参数传递。
注释:如果微软实现了这个重载,那就太好了。
我目前正在vb.net中使用此函数(基于其他答案):
1 2 3 | Private Shared Function SplitLines(text As String) As String() Return text.Split({Environment.NewLine, vbCrLf, vbLf}, StringSplitOptions.None) End Function |
它首先尝试在平台上拆分本地换行,然后返回到每个可能的换行。
到目前为止,我只需要在一节课上学这个。如果这改变了,我可能会使这个
以下是如何将这些线连接起来,以便更好地测量:
1 2 3 | Private Shared Function JoinLines(lines As IEnumerable(Of String)) As String Return String.Join(Environment.NewLine, lines) End Function |
好吧,事实上,分割应该做到:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //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]); } |
1 2 3 | string[] lines = text.Split( Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyStrings); |
removeEmptyStrings选项将确保您没有空条目,因为
(编辑以反映注释:)请注意,它还将丢弃文本中的真正空行。这通常是我想要的,但可能不是你的要求。
我不知道环境。新线,但我想这是一个很好的解决方案。
我的尝试是:
1 2 3 4 5 6 | string str ="Test Me Test Me Test Me"; var splitted = str.Split(' ').Select(s => s.Trim()).ToArray(); |
additional.trim删除可能仍然存在的任何
或(例如,在Windows上,但使用OS X换行符拆分字符串时)。可能不是最快的方法。
编辑:
正如注释正确指出的那样,这也会删除行开始处或新行提要之前的任何空白。如果需要保留该空白,请使用其他选项之一。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
愚蠢的回答:写一份临时文件,这样你就可以使用尊者
1 2 3 4 5 6 7 8 9 | var s ="Hello World"; var path = Path.GetTempFileName(); using (var writer = new StreamWriter(path)) { writer.Write(s); } var lines = File.ReadLines(path); |
其实很简单。
VB.NET:
1 2 3 | Private Function SplitOnNewLine(input as String) As String Return input.Split(Environment.NewLine) End Function |
C:
1 2 3 4 | string splitOnNewLine(string input) { return input.split(environment.newline); } |