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

我正在尝试突出显示markdown代码,但我遇到了.NET regex multiline选项的这种奇怪的行为。

以下表达式: ^(#+).+$适用于任何在线正则表达式测试工具:

在此处输入图像描述

但它拒绝使用.net:

在此处输入图像描述

它似乎没有考虑$标签,只是突出显示所有内容,直到字符串结束,无论如何。 这是我的C#

 RegExpression = new Regex(@"^(#+).+$", RegexOptions.Multiline) 

我错过了什么?

很明显,您的文本包含LF以外的换行符。 在.NET正则表达式中,一个点匹配任何char但是LF(换行符char, \n )。

请参阅多行模式 MSDN正则表达式参考

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

所以,使用

 @"^(#+).+?\r?$" 

.+?\r?$将在换行符之前延迟匹配除LF以外的任何一个或多个字符到第一个CR(可选)。

或者只使用否定的字符类:

 @"^(#+)[^\r\n]+" 

[^\r\n]+将匹配除CR / LF之外的一个或多个字符。

你有什么是好的。 你唯一缺少的是那个. 与换行符不匹配,即使使用多行选项也是如此。 你可以用两种不同的方式解决这个问题。

最简单的方法是使用RegexOptions.Singleline标志,该标志会将换行符视为字符。 这样, ^仍然匹配字符串的开头, $匹配字符串的结尾和. 匹配一切, 包括换行。

修复此问题的另一种方法(虽然我不会根据您的用例推荐它)是修改您的正则表达式以明确允许换行符。 要做到这一点,你可以只替换任何. with (?:.|\n)表示任何字符或换行符。 对于您的示例,您最终会得到^(#+)(?:.|\n)+$ 。 如果要确保首先存在非换行符,请添加一个额外的点: ^(#+).(?:.|\n)+$