【问题标题】:Why doesn't $ in .NET multiline regular expressions match CRLF?为什么 .NET 多行正则表达式中的 $ 不匹配 CRLF?
【发布时间】:2011-12-23 16:47:39
【问题描述】:

我注意到以下几点:

var b1 = Regex.IsMatch("Line1\nLine2", "Line1$", RegexOptions.Multiline);   // true
var b2 = Regex.IsMatch("Line1\r\nLine2", "Line1$", RegexOptions.Multiline); // false

我很困惑。 RegexOptions 的文档说:

多行: 多行模式。更改 ^ 和 $ 的含义,使其分别匹配任何行的开头和结尾,而不仅仅是整个字符串的开头和结尾。

由于 C# 和 VB.NET 主要用于 Windows 世界,我猜 .NET 应用程序处理的大多数文件使用 CRLF 换行符 (\r\n) 而不是 LF 换行符 (\n)。尽管如此,.NET 正则表达式解析器似乎无法将 CRLF 换行符识别为 行尾

我知道我可以解决这个问题,例如,通过匹配 Line1\r?$,但它仍然让我觉得很奇怪。这真的是 .NET 正则表达式解析器的预期行为还是我错过了一些隐藏的 UseWindowsLinebreaks 选项?

【问题讨论】:

    标签: c# .net regex line-breaks


    【解决方案1】:

    来自 MSDN:

    默认情况下,$ 只匹配输入字符串的结尾。如果您指定 RegexOptions.Multiline 选项,它将匹配换行符 (\n) 或输入字符串的结尾。但是,它不匹配回车/换行字符组合。要成功匹配它们,请使用子表达式 \r?$ 而不仅仅是 $。

    http://msdn.microsoft.com/en-us/library/yd1hzczs.aspx#Multiline

    所以我不能说为什么(与其他语言的正则表达式的兼容性?),但至少它是有意的。

    【讨论】:

    • 令人惊讶,但至少定义明确。感谢您挖掘它!
    • 有趣的是,$ 匹配 positionnot 一个 literal 的正则表达式实现被广泛接受(和定义)我>。所以 MSDN 说它匹配换行符也不完全正确。
    • +1 在多行模式下,$ 匹配之前有一个 long 历史(因此是一个史无前例的先例)。默认情况下使其行为不同对于MS来说是一个糟糕的举动。但是,他们可以添加一个 .NET 特定的修饰符以使 $ 匹配:(?=[\r\n]|\z)(这可能是您在此处寻找的表达式)。
    • 另一个令人费解的事情(与此一致)是.NET允许点匹配\r,即使它被设置为不匹配换行符。
    • 我在 GitHub 上创建了一张票,以便我们表达我们对这种行为的不满 github.com/dotnet/corefx/issues/28410
    猜你喜欢
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多