【问题标题】:Same Regex over same content returns 3 different results discriminated by environment相同内容上的相同正则表达式返回 3 个不同的结果,由环境区分
【发布时间】:2021-08-15 07:34:06
【问题描述】:

这是一段代码

        
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

当我在单元测试项目中运行此代码时,直接在 Framework 4.7.2 中的 TestMethod - 0 matches

当我在针对 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”也会返回0 matches

我在这里仍然没有得到图片,但显然是不同编辑器中的换行符。那为什么字符串生成器会这样做呢?

【问题讨论】:

  • 我可能没有直接的解决方案,但只有一件事..你能尝试在单行中使用整个文本吗?看到它在所有环境中仍然给出相同的结果。我怀疑操作系统及其处理行尾的方式。
  • @dotnetstep 但是如果我正在寻找^GO$,即start-GO-end,单行将如何工作?可以给我试试的模式吗?
  • @dotnetstep 试过 var content = "Script 1 Line 1;" + Environment.NewLine + "GO" + Environment.NewLine + "Script 1 Line 2;" + Environment.NewLine + "GO" + Environment.NewLine; -- 不走运
  • 你试过"^GO\r?$"吗?
  • 相关documentation。简而言之,“$”正在寻找\n,但根据环境,新行可以改为\r\n

标签: c# .net regex .net-standard-2.0


【解决方案1】:

在 MSDN(https://docs.microsoft.com/en-us/dotnet/standard/base-types/anchors-in-regular-expressions?redirectedfrom=MSDN) 中,它声明:

如果您将 $ 与 RegexOptions.Multiline 选项一起使用,则匹配也可以出现在行尾。请注意,$ 匹配 \n 但不匹配 \r\n(回车符和换行符的组合,或 CR/LF)。要匹配 CR/LF 字符组合,请在正则表达式模式中包含 \r?$。

当我在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 带回车。它与 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 不带回车。它与 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 带回车。它与 GO 不匹配。

因此,将^GO$ 更改为^GO\r?$ 即可。

【讨论】:

  • 这很奇怪。您可以在运行 match 之前输入 foreach (var c in content) Console.Write($"{(int)c} "); 以打印实际数据并显示它打印的内容吗?
  • 对不起,我收回我之前的声明。有用。现在将测试更多
  • @T.S.很好,它起作用了。实际上我也从这项研究中学到了一个新东西。
猜你喜欢
  • 2017-11-08
  • 2022-06-10
  • 1970-01-01
  • 2016-01-09
  • 2019-08-28
  • 2015-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多