Les expressions régulières en java avec regex

Une expression régulière est une chaîne de caractères String qui décrit un motif dans une séquence de caractères. On peut utiliser l'API regex pour:
  • Valider une séquence de caractères, par exemple, vérifier la validité d'un e-mail ou d'un mot de passe;
  • Chercher dans une chaîne de caractères;
  • Remplacer un motif ou un ensemble de caractères dans un String.
L'API java.util.regex a un seul interface et trois classes:
  • Classe Pattern: représentation compilée d'une expression régulière. Pour créer un pattern, vous devez invoquer une des ses méthodes public static compile, qui va retourner un objet Pattern. Ces méthodes acceptent des expressions régulières comme argument.
  • Classe Matcher: moteur de recherche de motif qui analyse la chaîne de caractères. Vous obtenez l'objet Matcher en appelant la méthode Matcher dans l'objet Pattern. Ces deux classes travaillent ensemble.
  • PatternSyntaxException: lève une exception lorsque l'expression régulière es invalide.

Classe Matcher

Les méthode de la classe Matcher:

No. Méthode Description
1 boolean matches() retourne true si la chaine vérifie un motif
2 boolean find() trouver la prochaine expression qui vérifie le motif
3 boolean find(int start) trouver la prochaine expression qui vérifie le motif à partir d'un indice de début

Classe Pattern

C'est la version compilé d'une expression régulière. elle est utilisé pour un motif ou un regex.

No. Méthode Description
1 static Pattern compile(String regex) compile le regex et retourne une instance de Pattern
2 Matcher matcher(CharSequence entree) crée un Matcher (analyseur) qui analyse la séquence en entrée
3 static boolean matches(String regex, CharSequence entree) compile et analyse la séquence en entrée.
4 String[] split(CharSequence c) retourne un tableau de sous-chaines qui commencent par le caractère c
5 String pattern() retourne la chaine de l'expression régulière

Exemple

import java.util.regex.*;

public class regexTest {

public static void main(String args[]) {
Pattern p;
Matcher m;
//compilation de la regex avec le motif : "a"
p = Pattern.compile("a");
//créer et associer le moteur à la regex sur la chaîne "ab"
m = p.matcher("ab");
//si le motif est trouvé
if(m.find()) {
System.out.println("motif trouvé");
}
}
}
motif trouvé

Syntaxe des expressions régulières

1- Méta-caractères

Les méta-caractères sont des caractères avec un sens ou d'une autre façon, comment le motif est construit. Par exemple, si vous précédez un méta-caractères par le caractère '\', celui-ci ne serait pas interprété par l'analyseur. Les méta-caractères supportés par les expressions régulières de java sont dans le tableau suivant:

Caractère Description
[ ] définie un ensemble de caractères à l'intérieur d'une
{ } Quantificateur
\ le caractère n'est pas considéré comme méta-caractère
^ Début de ligne
$ Fin de ligne
| Opérateur OU
? 0 ou une fois l'expression qui précède
* 0 ou plusieurs fois l'expression qui précède
+ un ou plusieurs fois l'expression qui précède
. Remplace n'importe quel caractère

Exemple:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class metaCaractresExemple {

public static void main(String[] args) {
System.out.println(
Pattern.matches(".c", "abc"));//false (. remplace seulement le a)
System.out.println(
Pattern.matches("..c", "abc"));//true (3ème caractère est c)
System.out.println(
Pattern.matches("...c", "abbc"));//true (4ème caractère est c)

System.out.println(Pattern.matches("\\d", "2"));//true (seulement un chiffre)
System.out.println(Pattern.matches("\\d", "332"));//false (plusieurs chiffres)
System.out.println(Pattern.matches(
"\\d","123abc"));//false (chiffres et caractères)

System.out.println(Pattern.matches(
"\\D*", "geek"));//true (Non-chiffre et apparait au moins une fois)
}
}
La méthode matches()appartient à la classe Matcher et Pattern, elle retourne true si le motif recherché existe dans le string.

2- Classes de caractères

Une classe de caractères est un ensemble de caractères. Les méta-caractères [...] signifie une classe de caractères à l'intérieur d'une expression régulière.On peut définir la plage avec le tiret '-'. Par exemple [0-9] représente les chiffres de 0 à 9.

[abc] a, b ou c
[^abc] Négation: Remplace toute l'alphabet sauf a,b et c
[a-zA-Z] Plage: Remplace tous les caractères de a à z et de A à Z
[a-d[m-p]] Union: Remplace les caractères de a à d ou de m à p: [a-dm-p]
[a-z&&[abc]] Intersection: Remplace l'ensemble de l'intersection de a,b et c avec les caractères de a à z
[a-z&&[^cd]] Soustraction: Remplace tous les caractères de a à z sauf c et d: [abe-z]
[a-z&&[^m-p]] Soustraction: de a à z sauf de m à p: [a-lq-z]

Exemple

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class metaCaractresExemple {

public static void main(String[] args) {
Pattern p;
Matcher m;
//tous les chiffre de 0 à 9 sauf 345
p = Pattern.compile("[0-9&&[^345]]");
m = p.matcher("7");
boolean b = m.matches();
System.out.println(b);
}
}
true

Classes de caractères prédéfinies

Ceux sont les classes déjà définies dans l'API Java:

Classe Description
. Tout caractère
\d Un chiffre: [0-9]
\D Tout caractère sauf les chiffres [^0-9]
\s Un caractère blanc: retour à la ligne, espace: [ \t\n\x0B\f\r]
\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 mot: [^\w]

Exemple

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ClassesDeCaracteresExemple {
public static void main(String args[]) {
//d: un chiffre
//+: 1 ou plusieurs chiffres
String regex = "\\d+";
Pattern p = Pattern.compile(regex);

String phrase = "l'an 2015 21";

Matcher m = p.matcher(phrase);

if (m.find()) {
//afficher le premier groupe
System.out.println("group 0:" + m.group(0));
}
}
}
group 0:2015
Dans cet exemple, le regex "\\d+" contient deux slash, parce que en java on ajoute toujours un '\' avant. \d signifie la plage entre 0 et 9 Si vous enlever le '+', seulement le premier chiffre trouvé sera considéré : 2.

3- Quantificateurs

Les quantificateurs vous permet de définir le nombre de répétition d'un caractère.

Quantificateurs Description
X? X se produit une fois au maximum
X+ Une ou plusieurs fois
X* zéro ou plusieurs fois
X{n} n fois
X{n,} n ou plusieurs fois
X{y,z} au moins y fois mais moins de z fois

Exemples

Motif Chaine Résultats
[abc]? a a
[abc]? aa aucun
[abc]? ab aucun
a? abdaaaba {a},{ },{ },{a},{a},{a},{ },{a}
a* abdaaaba {a},{ },{ },{aaa},{ },{a}
a+ abdaaaba {a},{aaa},{a}
a[3] aaaa aaa
a{3, 6} aaaaaaaa aaaaaa
[0-9]{4} Le bug de l'an 2038 est similaire au bug de l'an 2000 {2038}, {2000}

4- Groupes de captures

Les groupes de captures donnent la possibilité de traiter plusieurs caractères comme une seule unité ou un sous-motif. Par exemple, (abc) crée un seul groupe contenant les caractères "a", "b" et "c".

Les groupes de captures sont comptés par le nombre des parenthèses ouvrantes de gauche à droite. Dans l'expression (A(B(C))), il y a 4 groupes. Le groupe 0 contient toujours l'expression entière:
  1. Groupe 0 : (A(B(C)))
  2. Groupe 1 : (A)
  3. Groupe 2 : (B(C))
  4. Groupe 3 : (C)
Pour trouver en Java combien de groupes y a-t-il dans une expression, invoquez la méthode groupCount() de l'objet Matcher. La méthode groupCount() retourne un int qui représente le nombre total de groupes. Dans l'exemple suivant exemple, goupCount() retournerait le nombre 4.

La sous-chaîne de caractères capturée par le groupe est retournée par la méthode group(int).

Exemple 1:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Goup {

public static void main(String[] args) {

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("groupe "+i+" :"+m.group(i));

}
}
groupe 0 :ABC
groupe 1 :ABC
groupe 2 :BC
groupe 3 :C
Exemple 2

Ce programme crée une expression régulière qui lit et vérifie la validité d'un numéro de téléphone:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class regex_telephone {

public static void main(String[] args) {

String regex = "\\b(\\d{3})(\\d{4})(\\d{3})(\\d{3})\\b";
Pattern p = Pattern.compile(regex);
String tel = "2541724156348";

Matcher m = p.matcher(tel);

if (m.find()) {
System.out.println("Téléphone : ("
+ m.group(1) + ") " + m.group(2) + "-"
+ m.group(3) + "-" + m.group(4));
}
}
}
Téléphone : (254) 1724-156-348

5- Frontières de recherche

Vous pouvez rendre votre motif plus précis en indiquant l'emplacement du motif recherché et dire où commence et où fini.

limiteur Description
^ Début de ligne
$ Fin de ligne
\b Extrémité de mot.
\B Extrémité de non-mot.
\A Début de la séquence en entrée
\G Fin de l’occurrence précédente
\Z Fin de la séquence, sauf le caractère final
\z Fin de la séquence

Exemples

Motif Chaîne Résultats
^java$ java java
\s*java$ java java
^bonjour\w* bonjourblahblah bonjourblahblah
\bjava\B javascript est un langage de programmation java
\Gtest test test test
\btest\b ceci est un test test

Trouver un motif et le remplacer

L'API Regex donne la possibilité de trouver un texte et le remplacer avec un autre. En Java, on peut utiliser deux méthodes de la classe Matcher pour accomplir cette tache:
  • replaceFirst(String) : remplace la première occurrence seulement;
  • replaceAll(String) : Parcourt et remplace toutes les occurrences.
Exemple:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Remplacement {
public static void main(String[] args) {
Pattern p = Pattern.compile("bus");
Matcher m = p.matcher("Je voyage en bus");
String s = m.replaceAll("train");
System.out.println(s);
}
}
Je voyage en train
Références:
Java Doc : Regular Expressions
JavaPoint :  Java Regex
TutorialsPoint : Java - Regular Expressions
Developpez : Les expressions régulières avec l'API Regex de Java