Classes de caractères en Java Regex
Classes de caractères prédéfinies et personnalisées en Java regex — \d, \w, \s, plages, négations et intersections.
Une classe de caractères est la partie d'une expression régulière qui correspond à un caractère parmi un ensemble de caractères autorisés. Chaque fois que vous écrivez \d, [aeiou] ou [^0-9], vous utilisez une classe de caractères. Ce sont les plus petits blocs de construction de presque tous les patterns utiles, et le moteur java.util.regex de Java vous en propose trois types : des raccourcis prêts à l'emploi comme \d, des ensembles personnalisés définis dans [...], et des classes nommées compatibles Unicode comme \p{Lower}. Maîtrisez-les et le reste des regex devient naturel.
Ce chapitre couvre les trois types — classes entre crochets personnalisées avec plages et négation, raccourcis prédéfinis, opérations d'ensemble (union, intersection, soustraction) et classes nommées Unicode/POSIX — puis les réunit dans un programme exécutable. Si vous débutez en Java regex, commencez par l'introduction aux regex et la syntaxe des regex.
Classes personnalisées : crochets, plages et négation
La classe entre crochets [...] correspond à n'importe quel caractère unique listé à l'intérieur. Listez les caractères un par un, ou utilisez un trait d'union pour exprimer une plage. Placez ^ juste après le crochet ouvrant pour nier l'ensemble — correspondre à n'importe quel caractère qui n'est pas listé.
"[abc]" // matches one 'a', 'b', or 'c'
"[a-z]" // any one lowercase letter (a range)
"[A-Za-z0-9]"// any letter or digit (three ranges in one class)
"[^aeiou]" // any single character that is NOT a vowelÀ l'intérieur d'une classe, la plupart des métacaractères perdent leur signification spéciale, vous n'avez donc que rarement besoin de les échapper. Un ], ^, - ou \ littéral fait exception — échappez-les, ou positionnez-les de manière à ce qu'ils ne puissent pas être mal interprétés (un - en première ou dernière position est un trait d'union littéral, pas une plage).
java.util.regex.Pattern p = java.util.regex.Pattern.compile("[-+0-9]");
System.out.println(p.matcher("-").find()); // true: leading - is literal
System.out.println(p.matcher("*").find()); // falseClasses prédéfinies : les raccourcis
Java fournit des raccourcis pour les ensembles que vous utilisez constamment. Chaque forme en minuscule possède un complément en majuscule qui correspond à tout ce que la forme minuscule ne correspond pas.
| Raccourci | Correspond à | Classe équivalente |
|---|---|---|
. | tout caractère sauf les terminateurs de ligne | — |
\d | un chiffre | [0-9] |
\D | un non-chiffre | [^0-9] |
\w | un caractère de mot | [a-zA-Z_0-9] |
\W | un caractère non-mot | [^a-zA-Z_0-9] |
\s | un caractère d'espacement | [ \t\n\x0B\f\r] |
\S | un caractère non-espacement | [^\s] |
\d s'écrit "\\d" dans un littéral de chaîne, et \w devient "\\w". Oublier la deuxième barre oblique inverse est l'erreur Java regex la plus courante — "\d" ne compilera même pas.String digits = "\\d+"; // regex is \d+ (one or more digits)
String word = "\\w+"; // regex is \w+
"abc123".replaceAll("\\d", "#"); // "abc###"Négation, intersection et union
Une classe entre crochets est une union par défaut — listez [abcxyz] et vous correspondez à l'un des six. Java ajoute deux opérateurs d'ensemble à l'intérieur des classes. L'opérateur && forme une intersection (ne correspond qu'aux caractères présents dans les deux ensembles), et imbriquer une classe dans une autre permet de soustraire.
| Construction | Signification |
|---|---|
[a-d[m-p]] | union : a–d ou m–p |
[a-z&&[aeiou]] | intersection : lettres minuscules qui sont des voyelles |
[a-z&&[^aeiou]] | soustraction : lettres minuscules qui ne sont pas des voyelles (consonnes) |
"[a-z&&[^aeiou]]" // all lowercase consonants
"[\\p{L}&&[^\\p{Lu}]]" // any letter that is not uppercaseLa négation avec ^ inverse une classe entière ; l'intersection avec && la réduit. Choisir le bon opérateur maintient les patterns lisibles au lieu d'accumuler des alternances.
Classes nommées Unicode et POSIX
Pour tout ce qui dépasse l'ASCII, utilisez la famille \p{...}. Ces classes nommées connaissent les catégories Unicode et les groupes de style POSIX, et \P{...} est la forme niée. Elles sont indispensables dès que vos données contiennent des lettres accentuées, des scripts non latins, ou si vous souhaitez simplement des noms révélateurs d'intention.
| Classe | Correspond à |
|---|---|
\p{Lower} | une lettre ASCII minuscule ([a-z]) |
\p{Punct} | un caractère de ponctuation |
\p{Alnum} | une lettre ASCII ou un chiffre |
\p{L} | n'importe quelle lettre Unicode (avec UNICODE_CHARACTER_CLASS) |
\p{IsDigit} | un chiffre Unicode |
// Make \w, \d, \s honor full Unicode, not just ASCII:
java.util.regex.Pattern uni =
java.util.regex.Pattern.compile("\\w+", java.util.regex.Pattern.UNICODE_CHARACTER_CLASS);
System.out.println(uni.matcher("café").results().count()); // 1: "café" is one wordExemple pratique : tous les types de classes sur une seule chaîne
Ce programme construit un petit assistant, count, qui indique combien de caractères d'une chaîne exemple une classe à un caractère fait correspondre. Faire passer la même chaîne à travers les classes chiffre, mot, espacement, plage, négation, intersection, le point et une classe POSIX rend les relations entre eux concrètes — et montre une classe faisant un vrai travail dans un pattern plus large.
Ce qu'il faut retenir de l'exécution :
\det[0-9]rapportent tous deux 13 pour cette chaîne — ils sont exactement équivalents pour les entrées ASCII. Une classe prédéfinie n'est qu'un nom intégré pour un ensemble que vous pourriez écrire à la main, donc utilisez le raccourci pour la lisibilité.\Det[^0-9]rapportent tous deux 30, le complément des 13 chiffres dans une chaîne de 43 caractères (13 + 30 = 43). Un raccourci en majuscule et une classe entre crochets niée sont deux façons d'écrire le même complément.[a-z&&[aeiou]]rapporte 3 — uniquement les voyelles minuscules, à savoir leede Order, leode cost et leide ship-by. LeOmajuscule de Order est en majuscule, donc l'intersection l'exclut. Le point :&&réduit une classe aux caractères présents dans les deux ensembles plutôt que de les unir, donc les voyelles majuscules ne correspondent jamais.- Le point a correspondu à 43, chaque caractère y compris les espaces et la ponctuation, car cette chaîne sur une seule ligne n'a pas de terminateur de ligne pour arrêter
.. Le point est la classe la plus large de toutes, ce qui est exactement la raison pour laquelle vous le remplacez généralement par une classe plus précise. - Le pattern
[A-Z]\da trouvéA7: les classes de caractères ne servent pas qu'au comptage — combinées en séquence, elles valident une structure, ici une lettre immédiatement suivie d'un chiffre.\p{Punct}a séparément trouvé 9 signes de ponctuation, montrant que les classes POSIX nommées fonctionnent aux côtés des raccourcis.
Exercice
Pour aller plus loin
Une classe de caractères correspond à un seul caractère ; l'étape suivante est de contrôler combien d'entre eux vous faites correspondre et quoi faire avec le résultat :
- Quantificateurs regex — ajoutez
+,*,?et{n,m}pour qu'une classe corresponde à une suite de caractères. - Groupes de capture — enveloppez une classe dans
(...)pour extraire la sous-chaîne correspondante. - Pattern et Matcher — l'API utilisée dans chaque exemple ci-dessus, en profondeur.
- Drapeaux regex —
CASE_INSENSITIVE,UNICODE_CHARACTER_CLASSet autres qui modifient le comportement des classes.