0

I got two strings A and B.

string A = @"Hello_
Hello_
Hello_";

string B = @"World
World
World";

I want to add these two strings together with a function call which could look like this:

string AB = ConcatMultilineString(A, B)

The function should return:

@"Hello_World
Hello_World
Hello_World"

The best way to do this for me was splitting the strings into an array of lines and then adding all lines together with "\r\n" and then returning it. But that seems bad practice to me since mulitple lines are not always indicated with "\r\n".

Is there a way to do this which is more reliable?

Blightbuster
  • 481
  • 7
  • 16
  • Is your problem [how to split line](https://stackoverflow.com/q/1508203/1997232)? – Sinatr Jul 05 '18 at 14:34
  • 1
    multiple lines are separated by `Environment.NewLine`. you can use this platform-specific constant if you are uncomfortable with a hardcoded `\r\n`. Do you need to deal with cases where both strings can have a different number of lines? there sure is a LINQ one-liner possible if you want to avoid arrays and loops. – Cee McSharpface Jul 05 '18 at 14:36
  • @dlatikay: The problem may be bigger than platform specific characters. You can have a mix of `\r\n` (new paragraph, Return in Word) and `\n` (new line in same paragraph, Shift+Return in Word). Though that is not an issue if the string is actually defined in code like the OP has for his example, we don't know where the actual string will be coming from. – Flater Jul 05 '18 at 14:39
  • @Flater The strings are from a input on a website. Im not sure if a mixing of \n and \r\n will happen but I obviously prefer a foolproof solution. – Blightbuster Jul 05 '18 at 14:45
  • @dlatikay can you link a LINQ alternative? – Blightbuster Jul 05 '18 at 14:46

5 Answers5

2

For a one line solution:

var output = string.Join(System.Environment.NewLine, A.Split('\n')
                   .Zip(B.Split('\n'), (a,b) => string.Join("", a, b)));

We split on \n because regardless of whether it's \n\r or just \n, it will contain \n. Left over \r seem to be ignored, but you can add a call to Trim for a and b if you feel safer for it.

Matt Burland
  • 44,552
  • 18
  • 99
  • 171
  • Some systems use a lone `\r` as the line separator. – Andrew Morton Jul 05 '18 at 15:02
  • @AndrewMorton then you could certainly use `Split(new [] {'\n', '\r'})` – Matt Burland Jul 05 '18 at 15:23
  • `var output = string.Join(System.Environment.NewLine, A.Split('\n').Zip(B.Split('\n'), (a,b) => string.Join("", a.Trim(), b.Trim())));` Worked well in the end. Without the extra trim '\r' would still remain in the strings and cut the first part. – Blightbuster Jul 05 '18 at 16:25
0

Environment.NewLine is a platform-agnostic alternative to using "\r\n".

Pharylon
  • 9,796
  • 3
  • 35
  • 59
  • The problem may be bigger than platform specific characters. You can have a mix of `\r\n` (new paragraph, Return in Word) and `\n` (new line in same paragraph, Shift+Return in Word). Though that is not an issue if the string is actually defined in code like the OP has for his example, we don't know where the actual string will be coming from. – Flater Jul 05 '18 at 14:41
0

Environment.NewLine might be helpful to resolve the "mulitple lines are not always indicated with "\r\n""-issue

https://msdn.microsoft.com/de-de/library/system.environment.newline(v=vs.110).aspx

Edit:

If you dont know if multiple lines are separated as "\n" or "\r\n" this might help:

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

Empty lines are removed. If you dont want this use: StringSplitOptions.None instead.

See also here: How to split strings on carriage return with C#?

Gener4tor
  • 414
  • 3
  • 12
  • 40
  • The problem may be bigger than platform specific characters. You can have a mix of `\r\n` (new paragraph, Return in Word) and `\n` (new line in same paragraph, Shift+Return in Word). Though that is not an issue if the string is actually defined in code like the OP has for his example, we don't know where the actual string will be coming from. – Flater Jul 05 '18 at 14:41
0

This does as you asked:

static string ConcatMultilineString(string a, string b)
{
    string splitOn = "\r\n|\r|\n";
    string[] p = Regex.Split(a, splitOn);
    string[] q = Regex.Split(b, splitOn);

    return string.Join("\r\n", p.Zip(q, (u, v) => u + v));
}

static void Main(string[] args)
{
    string A = "Hello_\rHello_\r\nHello_";
    string B = "World\r\nWorld\nWorld";

    Console.WriteLine(ConcatMultilineString(A, B));

    Console.ReadLine();

}

Outputs:

Hello_World
Hello_World
Hello_World

Andrew Morton
  • 24,203
  • 9
  • 60
  • 84
0

I think a generic way is very impossible, if you will load the string that is created from different platforms (Linux + Mac + Windows) or even get strings that contain HTML Line Breaks or what so ever I think you will have to define the line break you self.

string a = getA();
string b = getB();
char[] lineBreakers = {'\r', '\n'};
char replaceWith = '\n';
foreach(string lineBreaker in lineBreakers)
{
    a.Replace(lineBreaker, replaceWith);
    b.Replace(lineBreaker, replaceWith);
}
string[] as = a.Split(replaceWith);
string[] bs = a.Split(replaceWith);
string newLine = Environment.NewLine; 
if(as.Length == bs.Length)
{
    return as.Zip(bs (p, q) => $"{p}{q}{newLine }")
}