Подтвердить что ты не робот

Почему\R ведет себя по-разному в регулярных выражениях между Java 8 и 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

Почему?

4b9b3361

Ответ 1

Документация Java не соответствует стандарту Unicode. Javadoc запотевает то, что должен соответствовать \R. Он гласит:

\R Любая последовательность строк Unicode, эквивалентна \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]

Эта документация по Java неверна. В разделе в разделе R1.6 Line Breaks, Unicode Technical Standard # 18 on Regular Expressions четко говорится:

Настоятельно рекомендуется, чтобы был метасимвол регулярного выражения, такой как "\ R", для сопоставления всех строк и последовательностей строк, перечисленных выше (например, в # 1). Это соответствует тому, что эквивалентно следующему выражению. Это выражение немного усложняется необходимостью избежать резервного копирования.

 (?:\u{D A}|(?!\u{D A})[\u{A}-\u{D}\u{85}\u{2028}\u{2029}]

Другими словами, он может соответствовать только кодовой строке CR + LF (возврат каретки + строка) последовательности или одной кодовой точки из этого набора при условии, что она а не только возврат каретки, за которым следует строка. Это потому, что ему не разрешено создавать резервные копии. CRLF должен быть атомарным для \R для правильной работы.

Итак, Java 9 больше не соответствует тому, что настоятельно рекомендует R1.6. Более того, теперь он делает то, что он должен был НЕ делать, а не делать, в Java 8.

Похоже, мне пора дать Шерману (читай: Xueming Shen) снова крик. Я работал с ним раньше по этим мелочным вопросам формального соответствия.