簡體   English   中英

為什么\ R在Java 8和Java 9之間的正則表達式中表現不同?

[英]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文檔不符合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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM