I'm experiencing an inconsistent behavior between a desktop .NET application and a web-based ASP.NET application (running under Visual Studio).
In both, I use the same regular expression:
Dim mStart As Match = Regex.Match(s, "^((<|⏸)(?<tag>\w+)|\(|⸨)")
Then I evaluate:
If mStart.Groups("tag").Success Then
If mStart.Value.StartsWith("⏸") Then
' Unexpectedly true in ASP.NET when mStart.Value = "<mn"
End If
End If
In the desktop version, the condition is correctly false because mStart.Value is "<mn", and the first character is ASCII 60 (<).
In the ASP.NET version, mStart.Value is also "<mn" (Length = 3), and AscW(mStart.Value(0)) = 60, yet StartsWith("⏸") returns True, which is unexpected.
Additional detail:
In a previous execution of the same method, the input string s did start with "⏸mn", which correctly triggered the condition. But in a later call, when the string s = "<mn", the condition StartsWith("⏸") still evaluates to True, even though the first character is <.
What I’ve verified:
mStart.Value = "<mn"
mStart.Value.Length = 3
AscW(mStart.Value(0)) = 60
There are no invisible characters or leading BOMs in the string.
A character-by-character loop shows the first character is definitely <.
Hypotheses I considered:
Unicode normalization
String caching or reuse in Regex.Match
Hidden character due to HTML/XML decoding
Differences in Regex.Match().Value handling between ASP.NET and desktop .NET
Has anyone encountered anything similar? Could this be a bug, caching issue, or platform-specific behavior?
Any insights would be greatly appreciated.
It seems to be something to do with the way strings are compared using cultures.
In a simple console app, this outputs "FAIL":
Dim s = "<"
If s.StartsWith("⏸", StringComparison.CurrentCulture) Then
Console.WriteLine("FAIL.")
End If
Console.ReadLine()
Whereas this does not:
Dim s = "<"
If s.StartsWith("⏸", StringComparison.Ordinal) Then
Console.WriteLine("FAIL.")
End If
Console.ReadLine()
Solution: use StringComparison.Ordinal
or StringComparison.OrdinalIgnoreCase
.
Although, when I tried it with .NET 4.8.1 in ASP.NET and a console app, Threading.Thread.CurrentThread.CurrentUICulture.Name
(and CurrentCulture.name
) was "en-GB" in both cases.