Easiest way to split a string on newlines in .NET?

C#.NetStringSplit

C# Problem Overview


I need to split a string into newlines in .NET and the only way I know of to split strings is with the Split method. However that will not allow me to (easily) split on a newline, so what is the best way to do it?

C# Solutions


Solution 1 - C#

To split on a string you need to use the overload that takes an array of strings:

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

Edit:
If you want to handle different types of line breaks in a text, you can use the ability to match more than one string. This will correctly split on either type of line break, and preserve empty lines and spacing in the text:

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

Solution 2 - C#

What about using a StringReader?

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

Solution 3 - C#

You should be able to split your string pretty easily, like so:

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

Solution 4 - C#

Try to avoid using string.Split for a general solution, because you'll use more memory everywhere you use the function -- the original string, and the split copy, both in memory. Trust me that this can be one hell of a problem when you start to scale -- run a 32-bit batch-processing app processing 100MB documents, and you'll crap out at eight concurrent threads. Not that I've been there before...

Instead, use an iterator like this;

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

This will allow you to do a more memory efficient loop around your data;

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

Of course, if you want it all in memory, you can do this;

var allTheLines = document.SplitToLines().ToArray();

Solution 5 - C#

Based on Guffa's answer, in an extension class, use:

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

Solution 6 - C#

For a string variable s:

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

This uses your environment's definition of line endings. On Windows, line endings are CR-LF (carriage return, line feed) or in C#'s escape characters \r\n.

This is a reliable solution, because if you recombine the lines with String.Join, this equals your original string:

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

What not to do:

  • Use StringSplitOptions.RemoveEmptyEntries, because this will break markup such as Markdown where empty lines have syntactic purpose.
  • Split on separator new char[]{Environment.NewLine}, because on Windows this will create one empty string element for each new line.

Solution 7 - C#

Regex is also an option:

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

Solution 8 - C#

I just thought I would add my two-bits, because the other solutions on this question do not fall into the reusable code classification and are not convenient.

The following block of code extends the string object so that it is available as a natural method when working with strings.

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

You can now use the .Split() function from any string as follows:

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 parameter. When omitted it is
// set to StringSplitOptions.None
result = foo.Split("-", StringSplitOptions.RemoveEmptyEntries);

To split on a newline character, simply pass "\n" or "\r\n" as the delimiter parameter.

Comment: It would be nice if Microsoft implemented this overload.

Solution 9 - C#

I'm currently using this function (based on other answers) in VB.NET:

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

It tries to split on the platform-local newline first, and then falls back to each possible newline.

I've only needed this inside one class so far. If that changes, I will probably make this Public and move it to a utility class, and maybe even make it an extension method.

Here's how to join the lines back up, for good measure:

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

Solution 10 - C#

Well, actually split should do:

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

Solution 11 - C#

I did not know about Environment.Newline, but I guess this is a very good solution.

My try would have been:

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

The additional .Trim removes any \r or \n that might be still present (e. g. when on windows but splitting a string with os x newline characters). Probably not the fastest method though.

EDIT:

As the comments correctly pointed out, this also removes any whitespace at the start of the line or before the new line feed. If you need to preserve that whitespace, use one of the other options.

Solution 12 - C#

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

The RemoveEmptyStrings option will make sure you don't have empty entries due to \n following a \r

(Edit to reflect comments:) Note that it will also discard genuine empty lines in the text. This is usually what I want but it might not be your requirement.

Solution 13 - C#

Examples here are great and helped me with a current "challenge" to split RSA-keys to be presented in a more readable way. Based on Steve Coopers solution:

    string Splitstring(string txt, int n = 120, string AddBefore = "", string AddAfterExtra = "")
    {
        //Spit each string into a n-line length list of strings
        var Lines = Enumerable.Range(0, txt.Length / n).Select(i => txt.Substring(i * n, n)).ToList();
        
        //Check if there are any characters left after split, if so add the rest
        if(txt.Length > ((txt.Length / n)*n) )
            Lines.Add(txt.Substring((txt.Length/n)*n));

        //Create return text, with extras
        string txtReturn = "";
        foreach (string Line in Lines)
            txtReturn += AddBefore + Line + AddAfterExtra +  Environment.NewLine;
        return txtReturn;
    }

Presenting a RSA-key with 33 chars width and quotes are then simply

Console.WriteLine(Splitstring(RSAPubKey, 33, "\"", "\""));

Output:

Output of Splitstring();

Hopefully someone find it usefull...

Solution 14 - C#

Starting with .NET 6 we can use the new String.ReplaceLineEndings() method to canonicalize cross-platform line endings, so these days I find this to be the simplest way:

var lines = input
  .ReplaceLineEndings()
  .Split(Environment.NewLine, StringSplitOptions.None);

Solution 15 - C#

Silly answer: write to a temporary file so you can use the 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);

Solution 16 - C#

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

Solution 17 - C#

Very easy, actually.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRCIXView Question on Stackoverflow
Solution 1 - C#GuffaView Answer on Stackoverflow
Solution 2 - C#ClémentView Answer on Stackoverflow
Solution 3 - C#nikmd23View Answer on Stackoverflow
Solution 4 - C#Steve CooperView Answer on Stackoverflow
Solution 5 - C#Erwin MayerView Answer on Stackoverflow
Solution 6 - C#Colonel PanicView Answer on Stackoverflow
Solution 7 - C#evert823View Answer on Stackoverflow
Solution 8 - C#Kraang PrimeView Answer on Stackoverflow
Solution 9 - C#Rory O'KaneView Answer on Stackoverflow
Solution 10 - C#Maciek TalaskaView Answer on Stackoverflow
Solution 11 - C#MaxView Answer on Stackoverflow
Solution 12 - C#Serge WautierView Answer on Stackoverflow
Solution 13 - C#LargeView Answer on Stackoverflow
Solution 14 - C#Daniel RosenbergView Answer on Stackoverflow
Solution 15 - C#Colonel PanicView Answer on Stackoverflow
Solution 16 - C#maciejView Answer on Stackoverflow
Solution 17 - C#Skillaura13View Answer on Stackoverflow