相同内容的相同正则表达式 returns 3 个不同的结果因环境而异
Same Regex over same content returns 3 different results discriminated by environment
这是一段代码
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);
当我在 Roslyn 或 Framework 4.7.2 的“dotnetfiddle.com”中 运行 这段代码时 - 结果相同 - 2 matches
.
当我运行这段代码在单元测试项目中,直接在TestMethod
in Framework 4.7.2 - 0 matches
当我运行这个代码在class项目中编译目标netstandard2.0的方法时,-1 match
这是我需要解决的一个大问题
附加测试
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);
有了这个^^^,连“dotnetfiddle.com”returns0 matches
我仍然没有得到这里的图片,但显然不同编辑器中的换行符有关。那为什么字符串生成器要这样做?
在 MSDN(https://docs.microsoft.com/en-us/dotnet/standard/base-types/anchors-in-regular-expressions?redirectedfrom=MSDN) 中,它指出:
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.
当我在visual studio中打印content
的每个字节时,结果是
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
带回车 return。与 GO 不匹配。
而在 dotnetfiddle.com 和 python 中,结果是
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
无回车return。符合GO.
当我在dotnetfiddle中使用StringBuilder时,结果是
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
带回车 return。与 GO 不匹配。
因此,将 ^GO$
更改为 ^GO\r?$
即可。
这是一段代码
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);
当我在 Roslyn 或 Framework 4.7.2 的“dotnetfiddle.com”中 运行 这段代码时 - 结果相同 - 2 matches
.
当我运行这段代码在单元测试项目中,直接在TestMethod
in Framework 4.7.2 - 0 matches
当我运行这个代码在class项目中编译目标netstandard2.0的方法时,-1 match
这是我需要解决的一个大问题
附加测试
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);
有了这个^^^,连“dotnetfiddle.com”returns0 matches
我仍然没有得到这里的图片,但显然不同编辑器中的换行符有关。那为什么字符串生成器要这样做?
在 MSDN(https://docs.microsoft.com/en-us/dotnet/standard/base-types/anchors-in-regular-expressions?redirectedfrom=MSDN) 中,它指出:
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.
当我在visual studio中打印content
的每个字节时,结果是
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
带回车 return。与 GO 不匹配。
而在 dotnetfiddle.com 和 python 中,结果是
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
无回车return。符合GO.
当我在dotnetfiddle中使用StringBuilder时,结果是
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
带回车 return。与 GO 不匹配。
因此,将 ^GO$
更改为 ^GO\r?$
即可。