在行尾匹配

时间:2013-10-01 23:54:51

标签: java regex eol

这是一件非常简单的事情:替换一行

  • 可能包含尾随空白
  • 以'\ n','\ r','\ r \ n'或任何
  • 结尾

由一行不包含尾随空格并以'\ n'结尾。

我以为我可以通过一个简单的正则表达式来做到这一点。此处"\\s+$"无效,$在最终\n之前匹配。这就是\\z的原因。至少我在想。但

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

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


艾伦·摩尔的解释很有帮助,但刚才我发现在EOF取代任意的最后空白垃圾我能做到

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

而不是replaceAll。执行上述所有操作的简单解决方案是

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

我害怕,它不是很快,但它是可以接受的。

2 个答案:

答案 0 :(得分:1)

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

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

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

更新:为了处理这两种情况:(1)在行尾删除不需要的空格,以及(2)在没有不需要的空格的情况下添加换行符,I瘦你最好的选择是使用lookbehind:

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

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

答案 1 :(得分:0)

你能做一下这样的事吗?

 String result = myString.trim() + '\n';