用正则表达式去除末尾空格和多个空行

3
我希望能提供正则表达式,用于在C#编写的Visual Studio 2013扩展中使用。
我试图删除行尾空格,同时保留空行。我还想删除多个空行。现有的行结束符应该被保留(通常是回车换行)。
因此,以下文本(空格显示为下划线):
hello_world__


___hello_world_
__
__
hello_world

Would become:

hello_world

___hello_world

hello_world

我尝试了许多不同的模式来去除尾随空格,但我要么无法匹配尾随空格,要么丢失回车换行符。我还没有尝试删除多个空行。
这是我到目前为止尝试过的几种模式:
\s+$

(?<=\S)\s+$

2
有必要严格使用正则表达式吗?在删除字符串末尾的符号时,有更好的方法:TrimEnd和TrimStart。对于你的情况:str.TrimEnd(new char[] { '_' }) - Anton Semenov
我并不一定需要使用正则表达式,但我认为它适合我想要做的事情。也许我应该详细说明一下,但我正在将其应用于活动文档。我正在使用C#。这不必在单个操作中完成;多个操作也可以。 - sclarke81
这在单个操作中做起来会更困难。但是,它们是两个不同的操作,你也不需要一个来完成另一个。 - user557597
正则表达式比TrimEnd慢得多。 - user1945782
6个回答

3
感谢迄今为止的回答。虽然它们都不完全符合我的需求,但它们帮助我想出了我需要的东西。我认为问题在于VS2013中正则表达式存在一些奇怪的地方(请参见在Visual Studio中使用正则表达式)。对我而言,以下两个操作有效:
用“无”替换\ +(?=(\n|\r?$))
\r\n替换^\r?$(\n|\r\n){2,}

VS2013使用Dot-Net正则表达式引擎,这并不奇怪。只是提醒一下,微软(例如Windows)在他们提供的所有编辑框中都使用CRLF转换,并为此提供了一个API。因此,你的正则表达式没有意义。最后,你抄袭了我的表达式,回答了问题,然后将其标记为正确的答案。 - user557597
1
任何人给出的答案在我的情况下都没有真正起作用。它们都是好的正则表达式,并且在在线正则表达式测试器中运行良好,但它们在.NET或VS查找替换工具中对我不起作用。我发表了一个答案,因为我希望留下一个适用于我的情况的答案,以防对其他人有用。实际上,用于替换尾随空格的正则表达式来自@zolo,该链接建议进行修改。我使用多个答案作为灵感组合了删除多个空白行的正则表达式。 - sclarke81
我会检查Visual Studio是否实际使用了_Dot-Net_引擎。微软表示它确实使用了该引擎。当你说它不起作用时,我真的不确定你的意思,因为他们的引擎大多是一个缺少递归和一些额外类构造的pcre引擎,但这里没有涉及到任何这些内容。 - user557597

1

如果没有使用正则表达式,你总是可以通过行末标记将文档拆分,然后使用 TrimEnd 进行反馈(正如 Anton Semenov 所强调的那样)...

(假设将文本文档读入字符串中...)

//  Ascertain the linefeed...
string str = "This is a test    \r\nto see if I can force   \ra string to be broken \non multiple lines           \r\n into an array.";
string[] t = str.Split(new string[] { "\r\n", "\r", "\n" } ,StringSplitOptions.RemoveEmptyEntries);
thediv.InnerHtml = str + "<br /><br />";
foreach(string s in t)
{
    thediv.InnerHtml += s.TrimEnd() + "<br />";
}

我没有计时,但如果您希望避免正则表达式的复杂性(如果可能的话-请参见下文*),您应该会发现这个方法足够快地完成您想要的操作。
* 如果可以的话,我会避免使用正则表达式。这并不意味着我不使用它。正则表达式有其用武之地,但我认为它是一个最后的手段工具,例如符合格式的复杂灵活字符串-某些情况下替代方案将生成大量代码。尽可能减少使用正则表达式有助于提高代码的可读性。

1

使用以下方法可以去除多余的空白行和尾部空格:

(?:\r\n[\s-[\rn]]*){3,}

并替换为\r\n\r\n

请参见演示

要删除剩余的空格,您可以使用

(?m)[\s-[\r]]+\r?$

查看 演示2


请你能跟我解释一下这部分的意思吗? [\s-[\r]] - zolo
是的。字符类减法是.NET特定的功能。使用否定的字符类是那些不支持类减法或交集的正则表达式风格的解决方法。 - Wiktor Stribiżew

1
\ +(?=(\n|$))

任意数量的空格,并检查换行符后面是否有或者是文本的末尾(在你的字符串/文本中的最后一个字符)。 (当然,需要启用多行模式和全局模式)


1
有一件事,这也将匹配 here\t\t\t\t - user557597
非常正确。我应该只使用“+”而不是“\s+”。谢谢! - zolo
然后\ +不会让正则表达式匹配多于1行的内容。 - user557597
我不明白你的意思。在这里检查一下,看看我是否使用不当。 - zolo
我会这样说,你设置了全局标志//g,它找到了3个单独的匹配。 - user557597
显示剩余3条评论

0

\s 包括换行符,我只想搜索多个空格。我不知道 VS 的具体情况,但这应该可以解决:

[" "]*?$

0

作为单独的操作 -

删除尾随空格 (?m)[^\S\r\n]+$
删除带有文本的尾随空格行 (?m)(?<=\S)[^\S\r\n]+$

删除重复的空白行(连同空格修剪)

    # Find: (?>\A(?:[^\S\r\n]*\r\n)+)|(?>\r\n(?:[^\S\r\n]*(\r\n)){2,})
    # Replace: $1\r\n


    (?>
         \A 
         (?: [^\S\r\n]* \r \n )+
    )
 |  
    (?>
         \r \n 
         (?:
              [^\S\r\n]* 
              ( \r \n )                     # (1)
         ){2,}
    )

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