.net core limit \r\n to two lines

Viewed 204

I am getting a raw string of data, and I dont want to allow more than 2 new lines, I have no control over the source however I only want to show end of current line, and one gap line in any scenario, I can't work out a nice solution to do so.

Here is an example of the data:

"content": "Ldfjljildjbfd\r\n\r\nEihile\r\n\r\n\r\n\r\n\r\n\r\nErlgheiorjgoierjhg\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\neighi\r\n"

Here is an example of how it looks on the screen currently:

This is my example






It doesn't look particularly appealing

And here is an example of how I would like it to look:

This is my example

Much better here...

I've tried to do this in the dirtiest way possible, using something like this:

    private string DirtyLineClean(string body)
    {
        string body1 = body.Replace(@"\r\n\r\n\r\n\r\n\r\n\r\n", "\r\n\r\n");
        string body2 = body1.Replace(@"\r\n\r\n\r\n\r\n\r\n", "\r\n\r\n");
        string body3 = body2.Replace(@"\r\n\r\n\r\n\r\n", "\r\n\r\n");
        string body4 = body3.Replace(@"\r\n\r\n\r\n", "\r\n\r\n");

        return body4;
    }

Unfortunately that doesn't work at all.

Any suggestions welcome.

UPDATE

Using LarsTech answer, something isn't quite working. Here is my input:

Ldjgehgoierg\r\n\r\nErg\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nGergege\r\n\r\n\r\n\r\nErgerg\r\n\r\nEg\r\n\r\nEr\r\n\r\nGer\r\n\r\n\r\n\r\n\r\n\r\nrgg\r\n

Here is the output:

Ldjgehgoierg\r\n\n\r\n\nErg\r\n\n\r\n\n\r\n\n\r\n\n\r\n\n\r\n\n\r\n\n\r\n\nGergege\r\n\n\r\n\n\r\n\n\r\n\nErgerg\r\n\n\r\n\nEg\r\n\n\r\n\nEr\r\n\n\r\n\nGer\r\n\n\r\n\n\r\n\n\r\n\n\r\n\n\r\n\nrgg\r"
4 Answers

If you only want to show at maximum two line breaks, replace anything greater than two with the the first two only. This will preserve whether it was line feed or carriage return or both.

using System.Text.RegularExpressions;

var result = Regex.Replace(source, "((?:\r\n?|\n){2})[\r\n]+", "$1");

This regex will attempt to consume a "full" carriage-return+line-feed sequence first, otherwise it will match the individual components. For example, this would consider a sequence of \r\n\n as two and not three. Similarly the following would all be consumed at the start of the sequence: \n\r\n, \r\n\r\n, \r\r\n, \n\n, \n\r and \r\r (the last two only if the next value is not \n in which case they'd match greedily one of the others). After that it just matches any sequence since we plan to discard them anyways.

The replacement text "$1" indicates that the entire match (three or more carriage return/line feeds) should be replaced with the contents of the first capturing group (the first two, verbatim).

Regex Storm example

If you want to replace with the current platform's newlines instead, this should work:

var result = Regex.Replace(source, "(?:(?:\r\n?|\n){2})[\r\n]+", Environment.NewLine + Environment.NewLine);

In this case I've made the first group non-capturing (?:) since we no longer need to preserve the contents. This is a potential, minor optimization.

Note: regular expressions do have some overhead. If you are going to be doing this a lot, it would probably be appropriate to store the regex in a static field along with the RegexOptions.Compiled flag:

private static readonly Regex NewLineRegex = new Regex("((?:\r\n?|\n){2})[\r\n]+", RegexOptions.Compiled);

var result = NewLineRegex.Replace(source, "$1");

A Split and a Join can make this work:

var s= "Ldfjljildjbfd\r\n\r\nEihile\r\n\r\n\r\n\r\n\r\n\r\nErlgheiorjgoierjhg\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\neighi\r\n";
var lines = s.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries);
return string.Join(Environment.NewLine + Environment.NewLine, lines);

try using regex expressions:

var results = Regex.Split(s, @"\t|\n|\r").Where(m => !string.IsNullOrWhiteSpace(m)).Take(2);

Console.WriteLine(string.Join("\r\n\r\n", results)) // "\r\n\r\n" can be changed to however you'll like the results to be formatted as

and I dont want to allow more than 2 new lines

This is essentially what LarsTech already posted (I up-voted his answer), except I've tacked a Take(2) on the end so we only get two lines. This will work even if there is only one line in the original data:

string data = "Ldfjljildjbfd\r\n\r\nEihile\r\n\r\n\r\n\r\n\r\n\r\nErlgheiorjgoierjhg\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\neighi\r\n";
string twoLines = String.Join(Environment.NewLine, data.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Take(2));
Related