web-dev-qa-db-fra.com

Pourquoi \ R se comporte-t-il différemment dans les expressions régulières entre Java 8 et Java 9?

Le code suivant se compile dans les deux Java 8 & 9, mais se comporte différemment.

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);
        }
    }
}

Lorsque je l'exécute avec Java 8, il renvoie:

Chunk : 
En un lugar
de la Mancha
de cuyo nombre
no quiero acordarme

Mais quand je l'exécute avec Java 9 la sortie est différente:

Chunk : 
En un lugar
Chunk : de la Mancha
de cuyo nombre
Chunk : no quiero acordarme

Pourquoi?

77
Germán Bouzas

documentation Java n'est pas conforme à la norme Unicode. Le Javadoc brouille ce que \R est censé correspondre. Ça lit:

\R Toute séquence de saut de ligne Unicode est équivalente à \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]

Cette Java est boguée. Dans sa section sur les sauts de ligne R1.6, norme technique Unicode # 18 sur les expressions régulières indique clairement:

Il est fortement recommandé qu'il y ait un méta-caractère d'expression régulière, tel que "\ R", pour faire correspondre tous les caractères et séquences de fin de ligne répertoriés ci-dessus (par exemple, dans # 1). Cela correspondrait à quelque chose d'équivalent à l'expression suivante. Cette expression est légèrement compliquée par la nécessité d'éviter la sauvegarde.

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

En d'autres termes, il ne peut correspondre qu'à une séquence CR + LF (retour chariot + saut de ligne) à deux points de code ou bien un point de code unique de cet ensemble à condition qu'il ne s'agisse pas d'un simple retour chariot suivi d'un saut de ligne. C'est parce que c'est pas autorisé à sauvegarder. CRLF doit être atomique pour \R pour fonctionner correctement.

Donc Java 9 n'est plus conforme à ce que R1.6 recommande fortement. De plus, il fait maintenant quelque chose qu'il était censé ne PAS faire, et n'a pas fait, dans Java 8.

On dirait qu'il est temps pour moi de donner à Sherman (lire: Xueming Shen) à nouveau un cri. J'ai déjà travaillé avec lui sur ces questions de conformité formelle.

47
tchrist
63
user158037