.Net 正则表达式匹配 $ 与字符串的结尾而不是行的结尾,即使启用了多行
Posted
技术标签:
【中文标题】.Net 正则表达式匹配 $ 与字符串的结尾而不是行的结尾,即使启用了多行【英文标题】:.Net regex matching $ with the end of the string and not of line, even with multiline enabled 【发布时间】:2017-02-24 18:39:19 【问题描述】:我正在尝试突出显示降价代码,但遇到了 .NET 正则表达式多行选项的这种奇怪行为。
以下表达式:^(#+).+$
适用于任何在线正则表达式测试工具:
但它拒绝使用 .net:
它似乎没有考虑 $ 标记,并且只是突出显示直到字符串末尾的所有内容,无论如何。这是我的 C#
RegExpression = new Regex(@"^(#+).+$", RegexOptions.Multiline)
我错过了什么?
【问题讨论】:
点不能匹配没有 DOTALL 修饰符的 LF。你能分享一个dotnetfile吗? 你有一个 CR 结尾。使用@"^(#+).+?\r?$"
【参考方案1】:
很明显,您的文本包含 LF 以外的换行符。在 .NET 正则表达式中,点匹配除 LF 之外的任何字符(换行符,\n
)。
见Multiline Mode MSDN regex reference
默认情况下,
$
仅匹配输入字符串的结尾。如果您指定 RegexOptions.Multiline 选项,它匹配换行符 (\n
) 或输入字符串的结尾。但是,它不匹配回车/换行字符组合。要成功匹配它们,请使用子表达式\r?$
而不仅仅是$
。
所以,使用
@"^(#+).+?\r?$"
.+?\r?$
将延迟匹配除 LF 之外的任何一个或多个字符,直到换行符之前的第一个 CR(这是可选的)。
或者只使用否定字符类:
@"^(#+)[^\r\n]+"
[^\r\n]+
将匹配除 CR/LF 之外的一个或多个字符。
【讨论】:
不幸的是,当我使用Regex.Replacec
时,它会替换 \r
字符((我可以修复它吗?
@Deni35 好像有新问题,请教
可以用这种模式匹配行尾:(?=\r?$)
【参考方案2】:
你所拥有的是好的。您唯一缺少的是 .
不匹配换行符,即使使用多行选项也是如此。您可以通过两种不同的方式解决此问题。
最简单的方法是使用RegexOptions.Singleline 标志,它将换行符视为字符。这样,^
仍然匹配字符串的开头,$
匹配字符串的结尾,.
匹配所有包括换行符。
解决此问题的另一种方法(尽管我不会为您的用例推荐它)是修改您的正则表达式以明确允许换行符。为此,您可以将任何.
替换为(?:.|\n)
,这意味着任何字符或换行符。对于您的示例,您最终会得到^(#+)(?:.|\n)+$
。如果要确保首先有一个非换行符,请添加一个额外的点:^(#+).(?:.|\n)+$
【讨论】:
我想你误解了我的问题。我不想匹配新行。第二张图是我得到的,第一张图是我应该得到的。输入字符串“this is a \n #header \n but this is not”应该只匹配“#header”。目前,它匹配“#header but this is not” 请不要建议(?:.|\n)+
模式。它的效率非常低,并且可能由于它必须执行的回溯(或在惰性量词的情况下扩展)步骤的数量而导致系统冻结。在 .NET 中始终使用 .
和 (?s)
内联修饰符或 RegexOptions.Singleline
。您不需要每次都使用 [\s\S]
之类的解决方法,因为您可以在 .NET 正则表达式中使用修饰符组。例如:^.*\r?\n(?s:.*)
.以上是关于.Net 正则表达式匹配 $ 与字符串的结尾而不是行的结尾,即使启用了多行的主要内容,如果未能解决你的问题,请参考以下文章
正则前面的 (?i) (?s) (?m) (?is) (?im)
我需要一个正则表达式结果,不包括匹配模式的开头和结尾的子字符串