views:

366

answers:

4

Hi!

How do you split multi-line string into lines?

I know this way

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

looks a bit ugly to me and it looses empty lines. Do you know better solutions?

+5  A: 
  • If it looks ugly, just remove the unnecessary ToCharArray call.

  • If you want to split by either \n or \r, you've got two options:

    • Use an array literal – but this will give you empty lines for Windows-style line endings \r\n:

      var result = text.Split(new [] { '\r', '\n' });
      
    • Use a regular expression, as indicated by Bart:

      var result = Regex.Split(text, "\r\n|\r|\n");
      
  • If you want to preserve empty lines, why do you explicitly tell C# to throw them away? (StringSplitOptions parameter) – use StringSplitOptions.None instead.

Konrad Rudolph
Removing ToCharArray will make code platform-specific (NewLine can be '\n')
Konstantin Spirin
+5  A: 

You could use Regex.Split:

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

Edit: added '|\r' to account for (older) Mac line terminators.

Bart Kiers
I like the optional \r
Greg B
This won’t work on OS X style text files though, since these use only `\r` as line ending.
Konrad Rudolph
@Konrad Rudolph: AFAIK, '\r' was used on very old MacOS systems and is almost never encountered anymore. But if the OP needs to account for it (or if I'm mistaken), then the regex can easily be extended to account for it of course: \r?\n|\r
Bart Kiers
@Bart: I don’t think you’re mistaken but I *have* repeatedly encountered all possible line endings in my career as a programmer.
Konrad Rudolph
@Konrad, you're probably right. Better safe than sorry, I guess.
Bart Kiers
+2  A: 

If you want to keep empty lines just remove the StringSplitOptions.

var result = input.Split(System.Environment.NewLine.ToCharArray());
Jonas Elfström
NewLine can be '\n' and input text can contain "\n\r".
Konstantin Spirin
+1  A: 

Slightly twisted, but an iterator block to do it:

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

You can then call:

var result = input.Lines().ToArray();
JDunkerley
Iterator block rocks, but your code is too complex.
Konstantin Spirin