简单的多行正则表达式在 .NET 中失败,但在 ECMAScript 中成功 - 为啥?

Posted

技术标签:

【中文标题】简单的多行正则表达式在 .NET 中失败,但在 ECMAScript 中成功 - 为啥?【英文标题】:Trivial multiline regex fails in .NET but succeeds in ECMAScript - why?简单的多行正则表达式在 .NET 中失败,但在 ECMAScript 中成功 - 为什么? 【发布时间】:2019-02-20 23:33:55 【问题描述】:

我正在用 C# 编写一个快速实用程序来修改我的所有 Visual Studio C# 项模板以添加额外的 using ; 语句。我编写了一个简单的正则表达式来(hackishly)提取每个文件中的当前命名空间导入集,这样我就可以添加我想要的新导入而不会重复。

我使用Regex101.com 来测试我的正则表达式,然后再将它们插入到我的C# 程序中,但是当我在我的C# 程序中测试它们时它们不起作用。这让我很困惑,因为正则表达式本身很简单,它使用 .NET 和 ECMAScript 正则表达式通用的正则表达式约定并且即使使用RegexOptions.ECMAScript 兼容性选项它也会失败。

const String input = @"using System;
using System.Foo;

using Foo.Bar;

namespace Foo

    using Baz;

    class Qux
    

    
";

Regex regex = new Regex( @"^using ([\w\.]+)\;$", RegexOptions.Multiline | RegexOptions.ECMAScript );

Match match = regex.Match( input );

Assert.IsTrue( match.Success ); // `match.Success` is false when I run this code

我不明白为什么,因为\w^$ 和多行选项的行为在两个平台上表面上是相同的。

这是在 Regex101.com 中成功的截图:

这是显示它在 .NET 中失败的屏幕截图:

【问题讨论】:

如果你使用 CRLF 换行符,美元正好在它们之间匹配,所以在前面加上\r .Net regex matching $ with the end of the string and not of line, even with multiline enabled的可能重复 @SebastianProske Argh,谢谢。我认为.NET 的维护者应该添加一个RegexOptions.MatchCRLFNewLine! .NET 参考指南中没有很好地记录此设计问题。 【参考方案1】:

这是由于多行模式下的“$”匹配“\n”,而不是“\r\n”,后者是 Windows 上的默认换行符。解决方法就是在“$”换行符前面加上“\r?”,如下所示:

^using ([\w\.]+);\r?$

现在它将匹配“\n”和“\r\n”。

编辑

当您在 RegEx101 上输入多行文本时,他们使用 '\n' 作为换行符,这就是它在他们的网站上工作的原因。

【讨论】:

以上是关于简单的多行正则表达式在 .NET 中失败,但在 ECMAScript 中成功 - 为啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用 python 和 javascript 的慢正则表达式,但在 go 和 php 中快速失败

正则表达式在 g++ 4.9 下匹配,但在 g++-5.3.1 下失败

.Net 正则表达式匹配 $ 与字符串的结尾而不是行的结尾,即使启用了多行

perl 正则表达式 匹配多行的问题

JS 正则表达式^$详解,脱字符^与美元符$同时写表示什么意思?

正则表达式在文本编辑器(崇高)中工作,但在 python 中不工作 [重复]