78 votes

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

Le code suivant est compilé à la fois en Java 8 et 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);
        }
    }
}
 

Quand je le lance avec Java 8, il retourne:

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

Mais lorsque je le lance avec Java 9, le résultat est différent:

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

Pourquoi?

63voto

user158037 Points 2198

48voto

tchrist Points 47116

La documentation de Java est de la conformité avec la Norme Unicode. La Javadoc mistates ce qu' \R est censée correspondre. Il se lit comme suit:

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

Que la documentation Java est buggé. Dans son article sur R1.6 Sauts de Ligne, la Norme Technique Unicode n ° 18 sur les Expressions Régulières indique clairement:

Il est fortement recommandé qu'il y ait une expression régulière méta-caractère, comme "\R", pour la mise en correspondance de tous les caractères de fin de ligne et les séquences ci-dessus (par exemple, en #1). Cela correspondrait à quelque chose d'équivalent à l'expression suivante. Cette expression est un peu compliqué par la nécessité d'éviter de 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 à un des deux points de code CR+LF (retour chariot + saut de ligne) de la séquence ou de l'autre d'un seul point de code à partir de cet ensemble si c'est pas juste un retour chariot seul, qui est ensuite suivie par 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. En outre, il est maintenant en train de faire quelque chose qu'il était censé ne PAS faire, et ne pas faire, dans Java 8.

On dirait qu'il est temps pour moi de donner Sherman (lire: Xueming Shen) un hurlement de nouveau. J'ai travaillé avec lui avant sur ces choses sérieuses questions formelle de la conformité.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X