TL;DR: In .NET 11, RegexOptions.AnyNewLine makes ^ , $ , \Z , and . treat \r\n , \r , and the Unicode line breaks as newlines, not just \n . No more \r?$ , and no more values that end in an invisible carriage return. .NET 11 is at Release Candidate 2 right now: go-live licensed, but not final yet.
The character nobody can see
You write a regex that grabs a line. It passes every test, because the test strings were typed in C# with \n . Then a real file arrives from Windows, and every value you capture ends with \r .
using System.Text.RegularExpressions ;
var bug = Regex . Match ( "foo\r\nbar" , @".+$" , RegexOptions . Multiline ); Console . WriteLine ( bug . Value . Length ); // 4
Enter fullscreen mode
Exit fullscreen mode
Three letters, length 4. The fourth one is \r , and it only shows up later, when "foo" == value is mysteriously false.
The reason is old and simple. .NET's regex engine has always treated only \n as a newline. In Multiline mode, $ matches before \n , and .…