Same Regex over same content returns 3 different results discriminated by environment

Viewed 71

Here is the piece of code

        
var content = @"Script 1 Line 1;
GO
Script 1 Line 2;
GO
";
        
var regex = new Regex("^GO$", RegexOptions.Multiline);
MatchCollection mc = regex.Matches(content);
Debug.WriteLine(mc.Count);

When I run this code in "dotnetfiddle.com" in Roslyn or Framework 4.7.2 - same result - 2 matches.

When I run this code in the Unit Test project, directly in TestMethod in Framework 4.7.2 - 0 matches

When I run this code in the class method in project compiled targeting netstandard2.0, - 1 match

This is a major headache I need to solve

Additional Test

var sb = new StringBuilder();
sb.AppendLine("Script 1 Line 1;");
sb.AppendLine("GO");
sb.AppendLine("Script 1 Line 2;");
sb.AppendLine("GO");
sb.AppendLine();
var content = sb.ToString();
        
Console.WriteLine(content);
// ^^^ changed string creation ^^^
var regex = new Regex("^GO$", RegexOptions.Multiline);
MatchCollection mc = regex.Matches(content);
Console.WriteLine(mc.Count);

With this ^^^, even "dotnetfiddle.com" returns 0 matches

I am still not getting the picture here but obviously something about line breaks in different editors. Then why string builder is doing this?

1 Answers

In MSDN(https://docs.microsoft.com/en-us/dotnet/standard/base-types/anchors-in-regular-expressions?redirectedfrom=MSDN), it states:

If you use $ with the RegexOptions.Multiline option, the match can also occur at the end of a line. Note that $ matches \n but does not match \r\n (the combination of carriage return and newline characters, or CR/LF). To match the CR/LF character combination, include \r?$ in the regular expression pattern.

When I printed each byte of content in visual studio, the result was

83 99 114 105 112 116 32 49 32 76 105 110 101 32 49 59 13 10 71 79 13 10 83 99 114 105 112 116 32 49 32 76 105 110 101 32 50 59 13 10 71 79 13 10 with carriage return. It does not match GO.

while in dotnetfiddle.com and python, the result was

83 99 114 105 112 116 32 49 32 76 105 110 101 32 49 59 10 71 79 10 83 99 114 105 112 116 32 49 32 76 105 110 101 32 50 59 10 71 79 10 without carriage return. It matches GO.

When I used StringBuilder in dotnetfiddle, the result was

83 99 114 105 112 116 32 49 32 76 105 110 101 32 49 59 13 10 71 79 13 10 83 99 114 105 112 116 32 49 32 76 105 110 101 32 50 59 13 10 71 79 13 10 13 10 with carriage return. It does not match GO.

So changing ^GO$ to ^GO\r?$ will make it work.

Related