Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@

var regularExpressionReplaceResult = ReplaceLineBreak.ReplaceLineBreaksUsingTheRegularExpressionReplaceMethod();
Console.WriteLine(regularExpressionReplaceResult);

var removeLineBreaksResult = ReplaceLineBreak.RemoveLineBreaks();
Console.WriteLine(removeLineBreaksResult);
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,34 @@

namespace ReplaceLineBreaksInAStringCSharp;

public static class ReplaceLineBreak
public static partial class ReplaceLineBreak
{
public static string ReplaceLineBreaksUsingTheStringReplaceMethod()
{
const string text = "This is a line.\rThis is another line.";
var newText = text.Replace("\r\n", "\n").Replace("\r", "\n");

return newText;
}

public static string ReplaceLineBreaksUsingTheStringReplaceLineEndingsMethod()
{
const string text = "This is a line.\rThis is another line.";
var newText = text.ReplaceLineEndings("\n");

return newText;
}

public static string ReplaceLineBreaksUsingTheRegularExpressionReplaceMethod()
{
const string text = "This is a line.\rThis is another line.";
var newText = Regex.Replace(text, @"(\r\n|\r)", "\n");

return newText;
}
public const string Text = "Line one.\r\nLine two.\nLine three.\rLine four.";

public static string ReplaceLineBreaksUsingTheStringReplaceMethod() =>
ReplaceLineBreaksUsingTheStringReplaceMethod(Text);

public static string ReplaceLineBreaksUsingTheStringReplaceMethod(string text) =>
text.Replace("\r\n", "\n").Replace("\r", "\n");

public static string ReplaceLineBreaksUsingTheStringReplaceLineEndingsMethod() =>
ReplaceLineBreaksUsingTheStringReplaceLineEndingsMethod(Text);

public static string ReplaceLineBreaksUsingTheStringReplaceLineEndingsMethod(string text) =>
text.ReplaceLineEndings("\n");

public static string ReplaceLineBreaksUsingTheRegularExpressionReplaceMethod() =>
ReplaceLineBreaksUsingTheRegularExpressionReplaceMethod(Text);

public static string ReplaceLineBreaksUsingTheRegularExpressionReplaceMethod(string text) =>
LineBreakRegex().Replace(text, "\n");

public static string RemoveLineBreaks() =>
RemoveLineBreaks(Text);

public static string RemoveLineBreaks(string text) =>
text.ReplaceLineEndings(string.Empty);

[GeneratedRegex(@"\r\n|\r|\n")]
private static partial Regex LineBreakRegex();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,41 @@
namespace ReplaceLineBreaksInAStringCSharpBenchmarks;

[MemoryDiagnoser]
public class ReplaceLineBreakBenchmarks
public class ReplaceLineBreakBenchmarks
{
private const string ShortText = "This is a line.\rThis is another line.";

private const string MixedText =
"The quick brown fox jumps over the lazy dog.\r\n" +
"Pack my box with five dozen liquor jugs.\n" +
"How vexingly quick daft zebras jump.\r" +
"Sphinx of black quartz, judge my vow.\r\n" +
"Jackdaws love my big sphinx of quartz.\n" +
"The five boxing wizards jump quickly.\r" +
"Bright vixens jump; dozy fowl quack.\r\n" +
"Quick zephyrs blow, vexing daft Jim.\n" +
"Two driven jocks help fax my big quiz.\r" +
"Waltz, bad nymph, for quick jigs vex.\r\n" +
"Glib jocks quiz nymph to vex dwarf.\n" +
"Fickle jinx bog dwarves spy math quiz.\r";

[Params("Short", "Mixed")]
public string Input { get; set; } = "Short";

private string _text = ShortText;

[GlobalSetup]
public void GlobalSetup() => _text = Input == "Short" ? ShortText : MixedText;

[Benchmark]
public string StringReplace() => ReplaceLineBreak.ReplaceLineBreaksUsingTheStringReplaceMethod();
public string StringReplace() =>
ReplaceLineBreak.ReplaceLineBreaksUsingTheStringReplaceMethod(_text);

[Benchmark]
public string StringReplaceLineEndings() => ReplaceLineBreak.ReplaceLineBreaksUsingTheStringReplaceLineEndingsMethod();
public string StringReplaceLineEndings() =>
ReplaceLineBreak.ReplaceLineBreaksUsingTheStringReplaceLineEndingsMethod(_text);

[Benchmark]
public string RegexReplace() => ReplaceLineBreak.ReplaceLineBreaksUsingTheRegularExpressionReplaceMethod();
public string RegexReplace() =>
ReplaceLineBreak.ReplaceLineBreaksUsingTheRegularExpressionReplaceMethod(_text);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.8" />
<PackageReference Include="BenchmarkDotNet" Version="0.15.8" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,61 @@ namespace ReplaceLineBreaksInAStringCSharpTests;

public class ReplaceLineBreakTests
{
private const string Expected = "This is a line.\nThis is another line.";
private const string Expected = "Line one.\nLine two.\nLine three.\nLine four.";

[Fact]
public void WhenReplaceLineBreaksUsingTheStringReplaceMethod_ThenReturnStringOnOneLine()
public void WhenReplaceLineBreaksUsingTheStringReplaceMethod_ThenReturnStringWithUpdatedLineEndings()
{
var actual = ReplaceLineBreak.ReplaceLineBreaksUsingTheStringReplaceMethod();

Assert.Equal(Expected, actual);
}

[Fact]
public void WhenReplaceLineBreaksUsingTheStringReplaceLineEndingsMethod_ThenReturnStringWithUpdatedLineEnding()
public void WhenReplaceLineBreaksUsingTheStringReplaceLineEndingsMethod_ThenReturnStringWithUpdatedLineEndings()
{
var actual = ReplaceLineBreak.ReplaceLineBreaksUsingTheStringReplaceLineEndingsMethod();

Assert.Equal(Expected, actual);
}

[Fact]
public void WhenReplaceLineBreaksUsingTheRegularExpressionReplaceMethod_ThenReturnStringWithUpdatedLineEnding()
public void WhenReplaceLineBreaksUsingTheRegularExpressionReplaceMethod_ThenReturnStringWithUpdatedLineEndings()
{
var actual = ReplaceLineBreak.ReplaceLineBreaksUsingTheRegularExpressionReplaceMethod();

Assert.Equal(Expected, actual);
}

[Fact]
public void WhenRemoveLineBreaks_ThenReturnStringWithNoLineBreaksAtAll()
{
var actual = ReplaceLineBreak.RemoveLineBreaks();

Assert.Equal("Line one.Line two.Line three.Line four.", actual);
}

[Fact]
public void WhenReplacingCarriageReturnBeforeCarriageReturnLineFeed_ThenWindowsLineBreakDoubles()
{
const string text = "Line one.\r\nLine two.";

var wrongOrder = text.Replace("\r", "\n");
var rightOrder = text.Replace("\r\n", "\n").Replace("\r", "\n");

Assert.Equal("Line one.\n\nLine two.", wrongOrder);
Assert.Equal("Line one.\nLine two.", rightOrder);
}

[Fact]
public void WhenTextContainsALineSeparator_ThenOnlyReplaceLineEndingsMatchesIt()
{
const string text = "Line one.\u2028Line two.";

var replaceLineEndings = ReplaceLineBreak.ReplaceLineBreaksUsingTheStringReplaceLineEndingsMethod(text);
var replaceChain = ReplaceLineBreak.ReplaceLineBreaksUsingTheStringReplaceMethod(text);

Assert.Equal("Line one.\nLine two.", replaceLineEndings);
Assert.Equal(text, replaceChain);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand All @@ -10,13 +10,13 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.1" />
<PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="4.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PackageReference Include="coverlet.collector" Version="10.0.1">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
Loading