提问



我需要在.NET中将字符串拆分为换行符,我知道拆分字符串的唯一方法是使用Split方法。但是,这不允许我(轻松)拆分换行符,那么最好的方法是什么?[35]

最佳参考


要拆分字符串,您需要使用带有字符串数组的重载:


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


编辑:点击
如果要在文本中处理不同类型的换行符,可以使用匹配多个字符串的功能。这将正确分割任何类型的换行符,并保留文本中的空行和间距:


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

其它参考1


怎么用StringReader?[36]


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

其它参考2


您应该能够轻松地拆分字符串,如下所示:


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

其它参考3


根据Guffa的答案,在扩展课程中,使用:


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

其它参考4


尽量避免使用string.Split作为一般解决方案,因为你将在你使用函数的地方使用更多内存 - 原始字符串和拆分副本,都在内存中。相信我这可能是一个问题当你开始扩展时 - 运行一个处理100MB文档的32位批处理应用程序,你就会在8个并发线程中瘫痪。不是说我以前去过那里......


相反,使用这样的迭代器;


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


这将允许您围绕数据执行更高效的内存循环;


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


当然,如果你想要所有内存,你可以做到这一点;


var allTheLines = document.SplitToLines.ToArray();

其它参考5


对于字符串变量s:


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


这使用了你的环境对行结尾的定义。在Windows上,行结尾是CR-LF(回车,换行)或C#的转义字符\r\n


这是一个可靠的解决方案,因为如果你用String.Join重新组合这些行,这等于你的原始字符串:[37]


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





什么不该做:



  • 使用StringSplitOptions.RemoveEmptyEntries,因为这会破坏标记,例如Markdown,其中空行有语法用途。

  • 拆分分隔符new char[]{Environment.NewLine},因为在Windows上,这将为每个新行创建一个空字符串元素。


其它参考6


正则表达式也是一种选择:[38]


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

其它参考7


只是想我会添加我的两位,因为这个问题上的其他解决方案不属于可重用的代码分类并且不方便。下面的代码块扩展了string对象,以便在处理字符串时它可以作为一种自然的方法使用。


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


您现在可以使用任何字符串中的.Split()函数,如下所示:


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


要拆分换行符,只需将"\n""\r\n"作为分隔符参数。


评论: 如果微软实施了这种重载,那就好了。

其它参考8


我目前在VB.NET中使用此功能(基于其他答案):


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


它首先尝试拆分平台本地换行符,然后回退到每个可能的换行符。


到目前为止我只在一个类中需要这个。如果这个改变了,我可能会把它Public移到实用程序类,甚至可能使它成为一个扩展方法。


以下是如何加入线条,以获得良好的衡量标准:


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

其它参考9


嗯,实际上拆分应该做:


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

其它参考10


string[] lines = text.Split(
  Environment.NewLine.ToCharArray(), 
  StringSplitOptions.RemoveEmptyStrings);


RemoveEmptyStrings 选项将确保您在\\ n后面没有空条目


(编辑以反映评论:)请注意,它还会丢弃文本中的真正空行。这通常是我想要的,但可能不是你的要求。

其它参考11


我不知道Environment.Newline,但我想这是一个非常好的解决方案。


我的尝试本来是:


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


附加的.Trim删除可能仍然存在的任何\\ r或\\ n(例如,在Windows上但是使用os x换行符分割字符串时)。可能不是最快的方法。


编辑:


正如评论正确指出的那样,这也会删除行开头或新换行符之前的任何空格。如果需要保留该空格,请使用其他选项之一。

其它参考12


愚蠢的回答:写一个临时文件,这样你就可以使用古老的文件了
File.ReadLines [39]


var s = "Hello\r\nWorld";
var path = Path.GetTempFileName();
using (var writer = new StreamWriter(path))
{
    writer.Write(s);
}
var lines = File.ReadLines(path);

其它参考13


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

其它参考14


实际上非常简单。


VB.NET:


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


C#:


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