2013-10-01 47 views
1

這是一個非常瑣碎的事情:替換線相匹配的行尾

  • 可能含有尾隨空白
  • 由 '\ 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"); 

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

回答

1

實際上,\z是無關緊要的。在第一次匹配嘗試中,\s*消耗換行(\n)和\z成功,因爲它現在位於字符串的末尾。所以它用換行替換換行,然後它試圖在之後的位置處匹配換行,換行是字符串的結尾。它再次匹配,因爲\s*被允許匹配空字符串,所以它用另一個換行替換空的刺。

您可能會期望它繼續匹配任何東西,並用無限的換行替換它,但這不會發生。除非您重置它,否則正則表達式無法在相同位置匹配兩次。或者更確切地說,在相同的位置開始。在這種情況下,第一場比賽在位置#0開始,第二場在#1位置開始。

順便說一句,\s+$應該匹配字符串"\n"; $可以匹配字符串的最末尾以及字符串末尾的行分隔符之前。

更新:爲了處理這兩種情況:(1)得到在該行的結尾去掉不必要的空白,和(2)增加的情況下換行那裏沒有無用的空白,我瘦你最好的選擇是用後視:

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

這將仍然匹配每一行,但它只會匹配每行一次。

+0

*實際上,\ z是無關緊要的。* - 它不可能是因爲我真的不想替換中間的空格。 *'$'可以匹配字符串的末尾,也可以匹配字符串末尾的行分隔符。* - 我知道,這就是爲什麼我使用'\ z'來代替,因爲我只想在最後匹配。 – maaartinus

+0

關於'*'...原本我用的是'+',但是我想知道缺失行結尾的情況。我的錯。因此,現在'(s +'\ n')。replaceFirst(「\\ s + \\ z」,「\ n」)似乎可以工作,但對於這樣一項微不足道的任務而言,這很複雜。 – maaartinus

+0

不,我的意思是它在你的例子*中沒有任何作用。只有兩個位置,正則表達式可以開始匹配:在換行之前和之後。但我想我現在得到你;我會更新我的答案。 –

0

你可以像下面這樣做嗎?

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

不完全...我只能修剪正確,縮進必須保留。我發現了一個(相當醜陋的)解決方案,但是我真正的問題是正則表達式不能像我一直以爲的那樣工作(我使用正則表達式很多)。 – maaartinus