在C#中匹配换行符(\n)的正则表达式

46

好的,这个问题让我很困扰...... 我有一个由字符串组成的变量:

var newContent = string.Format("({0})\n{1}", stripped_content, reply)

新内容将会显示为:
(旧文本)
新文本

我需要一个正则表达式,可以去掉括号中包含换行符的所有文本,包括括号本身。

我能想到的最好方法是:

const string  regex = @"^(\(.*\)\s)?(?<capture>.*)";
var match= Regex.Match(original_content, regex);
var stripped_content = match.Groups["capture"].Value;

这个方法可以工作,但是我想具体匹配换行符(\n),而不是任何空白字符(\s)。

\n\\n\\\n替换\s都无法正常工作。

请帮我保持理智!

编辑:一个例子:

public string Reply(string old,string neww)
        {
            const string  regex = @"^(\(.*\)\s)?(?<capture>.*)";
            var match= Regex.Match(old, regex);
            var stripped_content = match.Groups["capture"].Value;
            var result= string.Format("({0})\n{1}", stripped_content, neww);
            return result;
        }

Reply("(messageOne)\nmessageTwo","messageThree") returns :
(messageTwo)
messageThree

你能否发布一个简短但完整的程序来演示问题?我现在很难拼凑起来。 - Jon Skeet
5个回答

96

如果你指定了RegexOptions.Multiline选项,那么你可以使用^$分别匹配行的开始和结束。

如果你不想使用这个选项,请记住一个换行可能是以下任何一种:\n\r\r\n,所以你应该使用类似于[\n\r]+或更精确地说:(\n|\r|\r\n)来代替仅查找\n


30
请注意,alternation不是贪婪的;如果您将正则表达式应用于 "\r\n",它只会匹配"\r"。我建议改用 (\n|\r\n?) 或者可能是 (\r\n?|\n)。 - Alan Moore
我无法使用多行选项使其正常工作。 (\n|\r|\r\n)解决了问题。在这种特殊情况下,即使我只插入了\n来匹配字符串,但仍需要\r\n才能匹配成功。 - Dabblernl
@AlanMoore 谢谢你的回复。我之前很困惑为什么\r\n会匹配两次。 - ToastyMallows

29

实际上它是有效的,但是选项相反,即

 RegexOptions.Singleline

2
太好了!这对我解决了问题!不知何故,使用多行选项时未忽略行尾。但是使用单行就可以了!+1 - Yustme
感谢您的建议,多行输入在“Singleline”模式下处理得非常好...但是行为不同,有时需要“Singleline”行为!我知道我的输入是多行的,所以我没有真正考虑就设置了“Multiline”选项...但在这种情况下,“.”(点)不匹配换行符,而这正是我想要的。将其设置为“Singleline”解决了此问题。在这种情况下,“$”匹配输入字符串的末尾也很方便。所以我们得到了教训:多行输入并不总是意味着应该使用“Multiline”选项! - TCC
我不知道这是否是原始发帖人想要的,但这正是我想要的!也就是在文本中搜索我的正则表达式,并有效地忽略换行符。谢谢。 - glaucon
SingleLine并不是MultiLine的相反概念。它们是具有不幸名称的不同概念,可以一起使用。 - Thomas Weller
你是个天才。 - Euan Gordon

5

你可能会在换行符 \n 前面有一个回车符 \r。尝试将 \s 替换为 (\r\n)。


4
< p >虽然看起来违反直觉,但您可以同时使用< code >Multiline和< code >Singleline选项。
Regex.Match(input, @"(.+)^(.*)", RegexOptions.Multiline | RegexOptions.Singleline)

第一个捕获组将包含第一行(包括 \r\n),第二个组将有第二行。

为什么:

首先,RegexOptions 枚举是 标志,因此可以与位运算符结合使用,然后

  • Multiline

^$ 匹配每行的开头和结尾(而不是输入字符串的开头和结尾)。

  • Singleline

句点 (.) 匹配每个字符(而不是除了 \n 之外的每个字符)

查看文档


3

我可能有点晚了,但仍然希望这能有所帮助。

我需要在两个井号之间获取多个标记。

例如输入:

## 标记1 ##
## 标记2 ##
## 标记3_a
标记3_b
标记3_c ##

这在我的情况下似乎有效:

var matches = Regex.Matches (mytext, "##(.*?)##", RegexOptions.Singleline);

当然,您可能想用自己的字符替换两端的双井号。

希望有帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接