Syntaxe des expressions régulières Java
Syntaxe des expressions régulières Java : caractères, classes, ancres, quantificateurs et constructions spéciales.
Une expression régulière est un mini-langage de modèles pour décrire du texte. Java l'implémente dans le package java.util.regex, et la syntaxe est le dialecte style Perl partagé par la plupart des langages modernes — avec une particularité propre à Java : chaque barre oblique inverse dans un motif doit être doublée dans un littéral de chaîne Java, car le compilateur en consomme une avant que le moteur regex ne la voie. Ce chapitre est une référence à cette syntaxe : les éléments de base que vous combinez pour rechercher, trouver et valider du texte.
Si vous débutez avec les expressions régulières en Java, commencez par l'Introduction aux Regex Java, puis revenez ici quand vous avez besoin du mémo complet de la syntaxe.
Littéraux et métacaractères
La plupart des caractères dans un motif se correspondent eux-mêmes : cat correspond aux trois lettres c, a, t. La puissance vient des métacaractères — des caractères ayant une signification spéciale que vous combinez en règles. Les douze que le moteur traite de façon particulière sont :
. ^ $ * + ? ( ) [ ] { } | \Pour faire correspondre l'un d'eux littéralement, échappez-le avec une barre oblique inverse. N'oubliez pas la règle du double-backslash pour les sources Java : un regex \. s'écrit "\\." dans le code.
Pattern.matches("a.c", "abc"); // true — '.' matches any char
Pattern.matches("a.c", "a.c"); // true — '.' also matches a literal dot
Pattern.matches("a\\.c", "abc"); // false — '\.' matches ONLY a literal dot
Pattern.matches("a\\.c", "a.c"); // trueClasses de caractères
Une classe de caractères entre crochets correspond à n'importe quel unique caractère d'un ensemble. Les plages utilisent un tiret, et un ^ en tête annule l'ensemble.
"[aeiou]" // any one lowercase vowel
"[a-z]" // any one lowercase letter
"[A-Za-z0-9]" // any letter or digit
"[^0-9]" // any character that is NOT a digitJava propose également des classes prédéfinies comme raccourcis. Voici celles que vous utilisez constamment :
| Raccourci | Équivalent | Correspond à |
|---|---|---|
. | — | Tout caractère sauf un terminateur de ligne |
\d | [0-9] | Un chiffre |
\D | [^0-9] | Un non-chiffre |
\w | [a-zA-Z0-9_] | Un caractère de mot |
\W | [^a-zA-Z0-9_] | Un caractère non-mot |
\s | [ \t\n\x0B\f\r] | Un caractère d'espacement |
\S | [^\s] | Un caractère non-espace |
La forme majuscule est toujours la négation de la forme minuscule. Consultez Classes de caractères Regex Java pour l'ensemble complet, y compris les classes POSIX et Unicode.
Quantificateurs : gourmands, réticents, possessifs
Un quantificateur indique combien de fois l'élément précédent peut se répéter. Par défaut, les quantificateurs sont gourmands — ils prennent autant que possible, puis reculent si le reste du motif l'exige. Ajoutez ? pour rendre un quantificateur réticent (correspondre aussi peu que possible), ou + pour le rendre possessif (prendre sans jamais lâcher).
| Quantificateur | Signification |
|---|---|
* | Zéro ou plusieurs |
+ | Un ou plusieurs |
? | Zéro ou un (optionnel) |
{n} | Exactement n |
{n,} | Au moins n |
{n,m} | Entre n et m |
"\\d{3}" // exactly three digits
"\\d{2,4}" // two to four digits
"a+" // one or more 'a'
"colou?r" // matches "color" and "colour"
"<.+>" // greedy: on "<a><b>" matches the whole "<a><b>"
"<.+?>" // reluctant: on "<a><b>" matches just "<a>"Pour une étude approfondie du comportement gourmand, réticent et possessif, consultez Quantificateurs Regex Java.
Ancres, frontières et alternance
Les ancres correspondent à une position, pas à un caractère. ^ est le début de l'entrée (ou de la ligne, en mode multiligne), $ est la fin, et \b est une frontière de mot — la position de largeur nulle entre un \w et un \W. L'alternance avec | correspond à l'un ou l'autre côté.
"^Hello" // "Hello" only at the start
"\\.txt$" // ".txt" only at the end
"\\bcat\\b" // "cat" as a whole word, not inside "category"
"cat|dog" // "cat" or "dog"
"^(cat|dog)$" // the whole string is exactly "cat" or "dog"Notez que | a une très faible priorité : ^cat|dog$ signifie (^cat)|(dog$), et non ^(cat|dog)$. Enveloppez les alternatives dans un groupe quand vous souhaitez que les ancres s'appliquent aux deux.
Groupes, rétro-références et indicateurs en ligne
Les parenthèses créent un groupe capturant — le moteur mémorise ce que chaque groupe a capturé, numérotés de gauche à droite à partir de 1. (?:...) est un groupe non-capturant quand vous avez seulement besoin d'appliquer un quantificateur. Une rétro-référence \1 correspond au même texte que celui capturé par le premier groupe. Les indicateurs en ligne comme (?i) modifient le comportement de correspondance sans paramètre séparé de Pattern.compile.
"(\\d{4})-(\\d{2})" // group 1 = year, group 2 = month
"(?:ab)+" // repeats "ab" without capturing it
"(\\w+) \\1" // a word followed by itself ("the the")
"(?i)java" // case-insensitive: matches "Java", "JAVA"
"(?m)^line" // multiline: ^ matches at each line startLes groupes capturants ont leur propre chapitre — Groupes Regex Java couvre les groupes nommés et comment extraire le texte capturé d'un Matcher. Les indicateurs en ligne comme (?i) et (?m) sont les équivalents intégrés dans le motif des indicateurs de Pattern.compile décrits dans Indicateurs Regex Java.
Un exemple concret : les constructions en action
Ce programme illustre une classe de chiffres avec un quantificateur, une alternance ancrée, une rétro-référence, la correspondance gourmande versus réticente, le raccourci \w+, et un indicateur insensible à la casse en ligne — tout en utilisant uniquement java.util.regex. La syntaxe ici pilote l'API Pattern et Matcher couverte dans Pattern et Matcher Regex Java.
Ce qu'il faut retenir de l'exécution :
\d{4}a trouvé à la fois1995et2011carfind()recherche chaque occurrence dans l'entrée, tandis qu'une classe associée à un quantificateur (\drépété{4}fois) est la façon canonique de correspondre à un champ de largeur fixe. Le double backslash dans"\\d{4}"est le littéral de chaîne Java qui produit le backslash simple que le moteur attend.Pattern.matches("cat|dog", "dog")a retournétruemais le même motif sur"catnap"a retournéfalse—matches()ancre implicitement la totalité de l'entrée, donc même sicatapparaît danscatnap, lenaprestant n'est pas capturé et la correspondance globale échoue.- La rétro-référence
\1a transformé(\w+) \1en "un mot suivi du mot identique", c'est pourquoi elle a signalétheetis— les deux répétitions — et ignoré chaque mot qui n'était pas immédiatement répété. Les rétro-références correspondent au texte capturé, pas au motif à nouveau. - Sur la même entrée
<a><b>, le gourmand<.+>a avalé toute la chaîne tandis que le réticent<.+?>s'est arrêté au premier>, ne donnant que<a>. Ce contraste unique est la correction de bug regex la plus fréquente que vous ferez jamais : ajoutez?à un quantificateur quand il prend trop. \w+a compté 3 jetons dansab, cd-ef!—ab,cdetef— car,,-et!sont tous des\W(caractères non-mot) qui brisent une séquence de caractères de mot. L'indicateur(?i)en ligne a ensuite fait correspondrejavaàJAVA, montrant que les indicateurs peuvent résider à l'intérieur du motif lui-même plutôt que seulement dansPattern.compile.