1

这是一件非常微不足道的事情:替换一行

  • 可能包含尾随空格
  • 以 '\n', '\r', '\r\n' 结尾或什么都没有

由不包含尾随空格并以“\n”结尾的行。

我想我可以通过一个简单的正则表达式来做到这一点。在这里,"\\s+$"不能作为$决赛之前的比赛\n。这就是为什么有\\z. 至少我是这么认为的。但

"\n".replaceAll("\\s*\\z", "\n").length()

返回 2。实际上,$\\z\\Z在这里做完全相同的事情。我很困惑...


Alan Moore 的解释是有帮助的,但就在我刚刚想到在 EOF 替换任意最终空白垃圾时,我可以做到

replaceFirst("\\s*\\z"", "\n");

而不是replaceAll. 做上述所有事情的一个简单解决方案是

replaceAll("(?<!\\s)\\s*\\z|[ \t]*(\r?\n|\r)", "\n");

恐怕,这不是很快,但可以接受。

4

2 回答 2

1

其实,这\z无关紧要。在第一次匹配尝试时,\s*使用换行符 ( \n) 并\z成功,因为它现在位于字符串的末尾。所以它用换行符替换换行符,然后尝试在换行符之后的位置匹配,也就是字符串的结尾。它再次匹配,因为\s*允许匹配空字符串,所以它用另一个换行符替换空字符串。

您可能希望它继续匹配任何内容并用无限换行符替换它,但这不可能发生。除非您重置它,否则正则表达式不能在同一位置匹配两次。或者更准确地说,同一个位置开始。在这种情况下,第一场比赛从位置 #0 开始,第二场比赛从位置 #1 开始。

顺便说一句,\s+$应该匹配字符串"\n"$可以匹配字符串的末尾以及字符串末尾的行分隔符之前。

更新:为了处理这两种情况:(1)在行尾去掉不需要的空格,(2)在没有不需要的空格的情况下添加换行符,我认为你最好的选择是使用后向:

line = line.replaceAll("(?<!\\s)\\s*\\z", "\n");

这仍然会匹配每一行,但每行只会匹配一次。

于 2013-10-02T00:53:59.157 回答
0

你能做如下的事情吗?

 String result = myString.trim() + '\n';
于 2013-10-02T00:05:39.190 回答