précédent | suivant | table des matières

expressions régulières

Sommaire
  1. Introduction
  2. Expressions régulières en Java
    1. Méthodes de Pattern et Matcher
  3. Syntaxe des expressions régulières :
    1. Caractères
    2. Méta-Caractères
    3. Classes de caractères
    4. Quantificateurs
    5. Groupe de capture
    6. Spécificateurs de frontière
    7. Look-ahead, Look-behind.
    8. Options
  4. Quelques expressions régulières

Des application de test, RegexSR, et JRegexpTester, et un tutoriel, et le tutoriel de SUN. (expressions régulières et automates)

1 Introduction.

Les expressions régulières ou rationnelles sont des expressions construites à partir de constantes  et d'opérateurs.

Les constantes sont :

Les opérateurs de base sont :

Les priorités habituellement utilisées sont (dans l'ordre décroissant) *, concaténation, et ou. On peut utiliser des parenthèses dans les expressions rationnelles. L'opérateur + est défini de la façon suivante : E+ ≡ E | E*.

On note Rat(A) l'ensemble des expressions rationnelles sur le vocabulaire A. A toute expression rationnelle E appartenant à Rat(A) correspond un langage L(E) défini de la façon suivante :

  • L(∅) = ∅
  • L(ε) = {ε}
  • L(A) = {a, a∈A}
  • L(E*) = (L(E))* avec {a}* = {ε, a, aa, aaa, ...}
  • L(E1 | E2) = L(E1) ∪ L(E2)
  • L(E1E2) = L(E1)L(E2) avec {a, b}{c, d} = {ac, ad, bc, bd}
éléments de théorie des automates Eléments de théorie des automates,
Jacques Sakarovitch
(vuibert informatique)

L'appariement (concordance) d'une expression rationnelle avec une chaîne de caractères consiste à trouver dans la chaîne de caractères les occurrences d'éléments de L(E).

2 Expressions régulières en Java.

Trois classes interviennent dans les utilisations d'expressions régulières en Java :


try{
   Pattern p = Pattern .compile("a*b|c");
   String entree = "aabbbcab";
   Matcher m = p.matcher(entree);
   while (m.find())
      System.out.println(entree.substring(m.start(), m.end()));
}catch(PatternSyntaxException pse){
}
Affiche les résultats :

aab
b
b
c
ab

2.1 Méthodes de Pattern et Matcher.

static Pattern compile( String expreg) Compile la chaîne exrpreg en un Pattern. Lève une exception PatternSyntaxException si la syntaxe de expreg n'est pas correcte.
static Pattern compile( String expreg, int flags) La même chose que précédemment, en utilisant les options codées dans flags.
int flags() Retourne un entier représentant les options.
Matcher matcher (CharSequence entree) Crée un analyseur (Matcher) pour analyser la séquence de caractères entree.
static boolean matches(String expreg, CharSequence entree) Compile l'expression régulière et analyse la séquence de caractères entree. Equivalent à Pattern.compile(expreg).matcher(entree).matches()
String[] split ( charSequence entree, int limite) Retourne un tableau des sous-chaînes de entree qui sont séparées par des occurrences de chaînes  appariées à l'expression régulière. Le paramètre limite : contrôle le nombre de fois que l'expression régulière est appliquée. 
  • limite>0, l'expression régulière est appliquée au plus limite-1 fois. La dernière entrée du tableau contient la chaîne après la dernière occurrence de l'expression régulière analysée. Le tableau résultat a une taille égale à limite.
  • limite = 0 l'expression régulière est appliquée autant de fois que possible. les chaînes "" en fin de tableau sont supprimées du tableau.
  • limite<0 l'expression régulière est appliquée autant de fois que possible. La taille du tableau résultat est égale au nombre de concordances + 1.
String[] split ( charSequence entree) équivalent à split(entree, 0)
static String quote( String s) Créer une expression régulière qui s'apparie avec s. Retourne "\Q"+s+"\E"
String pattern() Retourne l'expression régulière sous forme de chaîne. (identique à toString() )
String toString() Retourne l'expression régulière sous forme de chaîne.


La classe Matcher accomplit les opérations de reconnaissance d'un motif sur une chaîne.

Il y a 3 sortes d'opérations de reconnaissance :

  1. la méthode boolean matches() qui essaie de reconnaître le motif sur la séquence en entier.
  2. la méthode boolean lookingAt() qui essaie de reconnaître le motif sur  la séquence à partir du début, et pas forcément jusqu'à la fin. Les méthodes start(), end() et group() permettent d'obtenir plus d'informations.
  3. les méthodes boolean find() et boolean find(int d) qui essaient de reconnaître le motif une partie de la séquence en entrée.Les méthodes start(), end() et group() permettent d'obtenir plus d'informations.

Cette classe permet aussi de remplacer les sous séquences reconnues par le Matcher, éventuellement en fonction de la chaîne reconnue.

Les méthodes de Matcher :


int start()
int start(int i)
Retourne l'indice du début de la chaîne appariée au motif, ou  l'indice du début de la chaîne appariée au groupe d'indice i du motif. Lève une exception IllegalStateException si la méthode est appelée sans qu'il y ait eut une opération de reconnaissance avant.
int end()
int end(int i)
Retourne l'indice de fin de la chaîne appariée au motif, ou  l'indice de fin de la chaîne appariée au groupe d'indice i du motif. Lève une exception IllegalStateException si la méthode est appelée sans qu'il y ait eut une opération de reconnaissance avant.
String group()
String group(int i)
Retourne la chaîne reconnue par une opération de reconnaissance précédente.
Lève une exception IllegalStateException si la méthode est appelée sans qu'il y ait eut une opération de reconnaissance avant.
int groupCount() Retourne le nombre de groupes reconnus.


Matcher region(int d, int f) Définit la région d'un Matcher, de d à f, et retourne la Matcher modifié. Lève une exception IndexOutOfBoundsException si un indice n'est pas correct.
int regionStart() Retourne l'indice du début de la région.
int regionEnd() Retourne l'indice de fin de la région.


boolean find()
boolean find(int d)
Retourne true si  l'analyse à partir du début ou de la fin de l'analyse précédente, ou de d, réussit, et false sinon. La recherche se fait dans la région.
boolean matches() Retourne true si la région entière peut être reconnue par le motif et false sinon.
boolean lookingAt() Retourne true si le motif peut être reconnu au début de la région et false sinon.

Dans les chaînes de remplacement des méthodes suivantes $i désigne le ième groupe reconnu par le Matcher avant remplacement.


Matcher appendReplacement(
          StringBuffer sb,
          String remplace)
  1. lit les caractères de la séquence en entrée et les concatène à sb s'ils ne font pas partie d'une sous séquence appariée au motif.
  2. concatène à sb la chaîne remplace pour le motif  reconnu par un appel de find précédent.
  3. la postion du Matcher est mise à end().

Cette méthode est utilisée de la façon suivante :
Pattern p = Pattern.compile("....");
Matcher m = p.matcher("....");
StringBuffer sb = new StringBuffer();
while(m.find())
   m.appendReplacement(sb, "...");
m.appendTail(sb);
StringBuffer appendTail(StringBuffer sb)
String replaceAll(String remplace)
Remplace chaque sous séquence de la séquence analysée qui s'apparie avec le motif , par la chaîne remplace, et retourne la chaîne ainsi formée. Cette méthode analyse toute la séquence en entrée, et il faut réinitialiser le Matcher pour recommencer une analyse.
String replaceFirst(String remplace)
Remplace la première sous séquence de la séquence analysée qui s'apparie avec le motif , par la chaîne remplace, et retourne la chaîne ainsi formée. 


3 Syntaxe des expressions régulières.

Une expression régulière est construite à partir de caractères et d'opérateurs. L'utilisation des différents caractères et opérateurs est expliquée dans les paragraphes qui suivent.

3.1 Caractères.

Les caractères utilisés dans une expression rationnelles sont les caractères unicode java, plus les caractères spéciaux suivants :

Caractère Sémantique.
\\ Le caractère anti-slash
\0n Le caractère de code octal n avec (0≤n≤7)
\0nn Le caractère de code octal nn avec (0≤n≤)
\0mnn Le caractère de code octal mnn avec (0≤m≤3 et 0≤n≤7)
\0hh Le caractère de code 0xhh
\0hhhh Le caractère de code 0xhhhh
\t Le caractère de tabulation '\u0009'
\n Le caractère de nouvelle ligne '\u000A'
\r Le caractère de retour en début de ligne '\u000D'
\a Le caractère sonnette '\u0007'
\e Le caractère d'échappement '\u001B'
\cx Le caractère de contrôle correspondant à x

3.2 Méta caractères.

Ce sont des caractères qui sont interprétés par l'analyseur. Pour qu'un méta-caractère ne soit par interprété par l'analyseur, il faut le faire précéder du caractère '\'. Les caractères '-' et ']' ont un statut spécial : dans un intervalle ce sont des méta-caractères, et en dehors d'un intervalle ils se comportent comme des caractères normaux.


Caractère Sémantique.
. Remplace n'importe quel caractère, sauf la fin de ligne.
? Opérateur portant sur l'expression précédente : 0 ou une fois l'expression précédente.
* Opérateur de Kleene : 0, 1 ou plusieurs fois l'expression précédente.
+ 1 ou plusieurs fois l'expression précédente.
[] Intervalle de caractères.
{} Quantificateur.
\ Le caractère qui suit n'est plus considéré comme un méta-caractère.
^ Négation ou début de ligne.
$ Fin de ligne.
| Opérateur ou.

3.3 Classes de caractères. Une classe de caractères est un ensemble de caractères : certaines classes sont prédéfinies dans l'API Java, d'autre peuvent être définies par le programmeur.
Classe Sémantique.
\d Un chiffre : équivalent à [0-9]
\D un caractère qui n'est pas un chiffre : équivalent à [^0-9]
\s Un caractère blanc : espace, tabulation, retour à la ligne ... équivalent à [ \t\n\r\f\x0B]
\S Un caractère non blanc : [^\s]
\w Un caractère de mot : [a-zA-Z_0-9]
\W Un caractère qui n'est pas un caractère de mot : [^\w]

Une classe de caractères peut être définie par le programmeur  en écrivant entre [ ] la liste des caracères de la classe, et en utilisant les opérateurs d'union (non marqué), d'intersection (&&) et de négation (^) :

[abc]
[a-z]
La classe des trois caractères a, b et c, ou la classe de tous les caractères de a à z.
[^abc] La classe de tous les caractères sauf a, b et c.
[a-zA-Z]
[a-z[A-Z]]
L'union des classes [a-z] et [A-Z].
[123abc&&[a-z]] L'intersection de la classe [123abc] et  de la classe [a-z]

Les classes de caractères POSIX sont :

Classe Sémantique.
\p{Lower}Une lettre minuscule : [a-z]
\p{Upper}Une lettre majuscule :[A-Z]
\p{ASCII}tout caractère ASCII :[\x00-\x7F]
\p{Alpha}Une lettre minuscule ou majuscule :[\p{Lower}\p{Upper}]
\p{Digit}Un chiffre : [0-9]
\p{Alnum}Une lettre ou un chiffre:[\p{Alpha}\p{Digit}]
\p{Punct}Ponctuation : un parmi !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
\p{Graph}Un caractère visible : [\p{Alnum}\p{Punct}]
\p{Print}Un caractère imprimable [\p{Graph}\x20]
\p{Blank}Espace ou tabulation: [ \t]
\p{Cntrl}Carcatère de contrôle : [\x00-\x1F\x7F]
\p{XDigit}Un chiffre hexadécimal [0-9a-fA-F]
\p{Space}Un espace : [ \t\n\x0B\f\r]

Les classes de caractères Java sont :

Classe Sémantique.
\p{javaLowerCase}Equivalent to java.lang.Character.isLowerCase()
\p{javaUpperCase}Equivalent to java.lang.Character.isUpperCase()
\p{javaWhitespace}Equivalent to java.lang.Character.isWhitespace()
\p{javaMirrored}Equivalent to java.lang.Character.isMirrored()

Les classes de caractères Unicode sont :

Classe Sémantique.
\p{InGreek}Un caractère grec.
\p{Lu}Une lettre majuscule.
\p{Sc}Un symbole monétaire.
\P{InGreek}Tout ce qui n'est pas un caractère grec.

3.4 Quantificateurs.

Les quantificateurs sont

Les quantificateurs précédents sont qualifiés de 3 façons différentes :

3.5 Groupes de capture.

Les parenthèses utilisées dans les expressions régulières permettent de créer des groupes de sous motifs. Par exemple :
(a((bc)(d))) définit 4 groupes :
Le motif en entier , même sans parenthèses, est le groupe de rang 0.
Une sous-chaîne reconnue par un groupe de capture est conservée, et peut être obtenue par la méthode group(int i). La méthode groupCount() retourne le nombre de groupes conservés lors d'une analyse.

groupe numéro
(a((bc)(d))) 0
(a((bc)(d))) 1
((bc)(d)) 2
(bc) 3
(d) 4

Exemple :


Pattern p = Pattern.compile("(a((b)(c)))");
Matcher m = p.matcher("abc");
if( m.matches())
   for(int i= 0; i<= m.groupCount(); ++i)
      System.out.println("\n"+"groupe "+i+" :"+m.group(i));
affiche les résultats suivants :

groupe 0 : abc
groupe 1 : abc
groupe 2 : bc
groupe 3 : b
groupe 4 : c

A l'intérieur d'un motif, on peut faire référence à un groupe du même motif en écrivant \i : i étant le numéro du groupe.

L'expression (\w\w)\1 permet de reconnaître des mots tels que titi, toto, tutu, zozo ...

Un groupe peut ne pas être capturé : il suffit de le faire commencer par (?: . On dit qu'on a un groupe pur.

Un groupe peut être utilisé avant son occurrence dans l'expression régulière :  (\2deux|(un))+ permet de reconnaître des chaînes reconnues par l'expression un(((un)+(deux){0,1})*).
Lors de l'analyse, au premier passage \2 n'a pas de valeur, il y a donc echec, mais au deuxième passage, il peut avoir été affecté de "un", et l'analyse continue.

3.6 Spécificateurs de frontière.

Les spécificateurs de frontière sont des indicateurs permettant de dire où commence ou où finit le motif.

^ Début de ligne. (en mode multiligne )
$ Fin de ligne. (en mode multiligne )
\b Extrémité de mot.
\B Extrémité de non mot.
\A Le début de la séquence à analyser.
\G L'analyse du motif qui suit \G suit exactement l'analyse précédente du motif.
\Z La fin de la séquence à analyser, moins le caractère final.
\z La fin de la séquence à analyser.

Exemple :

Expression Chaîne Trouvé(s)
 java  javascript  java
 java\b  javascript  rien
 java$  javascript  rien

3.7 Look-ahead et look-behind.

On peut conditionner l'analyse d'une expression régulière à la réussite de l'analyse d'une autre expression (Look-ahead positif: (?=, ou Look-behind positif(?<=), ou à l'échec de l'analyse d'une autre expression (Look-ahead négatif(?!) ou Look-behind négatif (?<! ).

exemples :

3.8 Options.

Les options (sauf CANON_EQ et LITERAL) peuvent être activées localement à l'intérieur d'une expression régulière. Quand les options sont embarquées, elles sont valable pour le groupe dans lequel elles sont embarquées, ou pour toute l'expression si elles sont en début d'expression.
Exemple :

Les options sont rendues effectives en utilisant la méthode compile de la classe Pattern : 
Pattern.compile("a*b", Pattern.COMMENTS | Pattern.CASE_INSENSITIVE)

CANON_EQ Autorise l'équivalence canonique : Un caractère peut être codé de deux façons différentes :
  • É un seul caractère de code \u00c9
  • deux caractères de codes  \u0045\u0301
Si CANON_EQ est positionné, les deux codages sont identiques.
CASE_INSENSITIVE Insensibilité à la casse.
(?i) permet d'activer l'option depuis l'expression régulière.
COMMENTS Autorise les espaces et commentaires dans l'expression régulière.
Un commentaire commence par # et va jusqu'à la fin de la ligne
(?x) permet de positionner l'option depuis l'expression régulière.
DOTALL Si DOTALL  est activé, le point peut aussi remplacer le caractère fin de ligne. Par défaut ce n'est pas la cas.
(?s) permet de positionner l'option depuis l'expression régulière.
LITERAL Le motif est traité tel quel sans notion de méta-caractère.
MULTILINE Autorise le mode multilignes : ^ et $ sont respectivement le début et la fin de ligne si le mode multiligne est activé, sinon c'est le début et la fin de chaîne en entrée.
(?m) permet d'activer l'option depuis l'expression régulière.
UNICODE_CASE Autorise les caractères unicode.
(?u) permet de positionner l'option depuis l'expression régulière.
UNIX_LINES Autorise le codage Unix des fins de ligne.
(?d) permet de positionner l'option depuis l'expression régulière.


4 Exemples d'expresssions régulières.
  1. Les nombres entiers en Java
  2. Les nombres flottants en Java : (\+|-)?(\d*\.\d+|\d+\.\d*)((e|E)(\+|-){0,1}\d+){0,1}
  3. Un identificateur Java :  [a-zA-Z_]\w*
  4. Un commentaire Java // :  //.*
  5. Un commentaire Java /* ... */ :  /\*[\u0000-\uffff]*?\*/
  6. Les immatriculations de véhicule en France (voir sur wikipédia) : 
      [1-9]([0-9]{0,2}([A-Z&&[^OUI]]|[A-P&&[^OUI]][A-Z&&[^OUI]]) |
            [0-9]{0,3}[Q-Z&&[^OUI]][A-Z&&[^OUI]] | 
            ([1-9]|[0-9]{2})[A-Z&&[^OUI]]{3} )(0[1-9]|[1-9][0-9]|2A|2B)
  7. Changement de format de date (mm/jj/aa devient jj-mm-aa) : 
    l'expression régulière :  (0[1-9]|1[0-2])/(0[1-9]|[1-2][0-9]|30|31)/([0-9]{2})
    et le remplacement : $2-$1-$3
  8. Une bibliothèque d'expressions régulières : Regular Expression Library

haut de la page