好的,根据悬赏所指定的明确要求,以下是答案:
我还需要删除任何末尾的换行符,但是我的正则表达式不行。如果有人能给我一个可以通过这个测试的正则表达式,我的悬赏就归他了:StripWhitespace("test\r\n \r\nthis\r\n\r\n") == "test\r\nthis"
所以这里是答案:
(?<=\r?\n)(\s*$\r?\n)+|(?<=\r?\n)(\r?\n)+|(\r?\n)+\z
或者在由@Chris Schmich提供的C#代码中:
string fix = Regex.Replace("test\r\n \r\nthis\r\n\r\n", @"(?<=\r?\n)(\s*$\r?\n)+|(?<=\r?\n)(\r?\n)+|(\r?\n)+\z", string.Empty, RegexOptions.Multiline);
现在让我们试着理解它。这里有三种可选模式,我愿意用
string.empty
来替换。
(?<=\r?\n)(\s*$\r?\n)+
- 匹配包含仅空格的一行或多行,前面有一个换行符(但不匹配第一个前置换行符)。
(?<=\r?\n)(\r?\n)+
- 匹配包含零或多个没有内容的空行,并以一个换行符为前缀(但不匹配第一个前置换行符)。
(\r?\n)+\z
- 匹配测试字符串末尾的一个或多个换行符(您称之为尾随换行符)
这满足了你的测试要求!同时,它也适用于
\r\n
和
\n
两种换行格式!试一下吧!我相信这将是最正确的答案,尽管更简单的表达式可以通过你指定的奖励测试,但这个正则表达式可以通过更复杂的条件。
编辑:@Will 指出上述正则表达式的最后一个模式匹配可能存在潜在缺陷,即它无法匹配测试字符串末尾包含空格的多个换行符。所以让我们把最后一个模式改成这样:
\b\s+\z
中的 \b 是单词边界(单词的开始或结束),\s+ 是一个或多个空格字符,\z 是测试字符串(“文件”)的结尾。因此,它现在将匹配包括制表符和空格在内的文件末尾的任何组合空格。我测试了 @Will 提供的两个测试用例。
所以现在一切都应该是这样的:
(?<=\r?\n)(\s*$\r?\n)+|(?<=\r?\n)(\r?\n)+|\b\s+\z
编辑 #2: 好的,@Wil 找到了最后一个正则表达式没有覆盖的可能情况。这种情况是指在任何内容之前文件开头有换行符的输入。因此,让我们添加一种模式来匹配文件的开头。
\A\s+
- \A
匹配文件的开头,\s+
匹配一个或多个空格字符。
现在我们有:
\A\s+|(?<=\r?\n)(\s*$\r?\n)+|(?<=\r?\n)(\r?\n)+|\b\s+\z
现在我们有四个匹配模式:
- 文件开头的空格
- 包含空格的多余换行符(例如:
\r\n \r\n\t\r\n
)
- 没有内容的多余换行符(例如:
\r\n\r\n
)
- 文件末尾的空格