![](/img/trans.png)
[英]Why do Java regular expressions behave differently on Linux and Windows?
[英]Why does \R behave differently in regular expressions between Java 8 and Java 9?
以下代碼在Java 8和9中編譯,但行為不同。
class Simple {
static String sample = "\nEn un lugar\r\nde la Mancha\nde cuyo nombre\r\nno quiero acordarme";
public static void main(String args[]){
String[] chunks = sample.split("\\R\\R");
for (String chunk: chunks) {
System.out.println("Chunk : "+chunk);
}
}
}
當我用Java 8運行它時,它返回:
Chunk :
En un lugar
de la Mancha
de cuyo nombre
no quiero acordarme
但是當我使用Java 9運行它時,輸出是不同的:
Chunk :
En un lugar
Chunk : de la Mancha
de cuyo nombre
Chunk : no quiero acordarme
為什么?
這是Java 8中的一個錯誤,它得到修復: JDK-8176029:“Linebreak matcher不等同於javadoc中所述的模式” 。
Java文檔不符合Unicode標准。 Javadoc誤認為\\R
應該匹配什么。 它寫道:
\\R
任何Unicode\ \ |[\ \\ \ \ \ \ ]
序列,相當於\ \ |[\ \\ \ \ \ \ ]
那個Java文檔是錯誤的。 在R1.6換行符一節中,正則表達式上的Unicode技術標准#18明確指出:
強烈建議使用正則表達式元字符,例如“\\ R”,以匹配上面列出的所有行結束字符和序列(例如,在#1中)。 這將對應於與以下表達式等效的內容。 由於需要避免備份,該表達式稍微復雜一些。
(?:\\u{DA}|(?!\\u{DA})[\\u{A}-\\u{D}\\u{85}\\u{2028}\\u{2029}]
換句話說,它只能匹配兩個碼點CR + LF(回車+換行)序列或者從該組中的單個碼點,只要它不只是單獨一個回車然后后跟一個換行。 那是因為它不允許備份 。 CRLF必須是原子的\\R
才能正常運行。
所以Java 9不再符合R1.6強烈推薦的內容。 而且,現在它正在做一些它在Java 8中應該做的事情,而不是做的事情。
看起來是時候讓謝爾曼(讀作:沉雪明)再次大喊大叫。 我之前和他一起處理過正式合規的這些細節問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.