Les expressions régulières
Transcription
Les expressions régulières
Les expressions régulières Daniel Tschirhart : Programmation Java V1.34 Daniel Tschirhart : Programmation Java V1.34 Les expressions régulières Le langage des expressions régulières est spécialement conçu et optimisé pour la manipulation de texte. Ce langage comprend deux principaux types de caractères : les caractères de texte littéral les méta caractères. C'est le jeu de méta caractères qui confère aux expressions régulières leur puissance de traitement. 2 Daniel Tschirhart : Programmation Java V1.34 Quelques expressions régulières simples (1) Soit à rechercher dans un document le mot elvis. Spécifier l’expression suivante : 1. elvis recherchera tous les mots contenant elvis soit : elvis, elvise, pelvis, … 3 Daniel Tschirhart : Programmation Java V1.34 Quelques expressions régulières simples (2) L’expression précédente peut être améliorée de façon suivante : 2. \belvis\b \b est un méta caractère qui signifie chercher le début ou la fin d’un mot. En spécifiant cette expression on ne cherchera que le mot elvis. 4 Daniel Tschirhart : Programmation Java V1.34 Quelques expressions régulières simples (3) Supposons rechercher sur la même ligne le mot elvis suivi de tous les mots précédents le mot concert. Le « . » est un méta caractère signifiant n’importe quel caractère excepté le caractère newline. Le caractère « * » répète le nombre de fois nécessaire le méta caractère ou le caractère précédent. Ainsi « .* » signifie les tous caractères excepté newline. L’expression suivante effectue la recherche désirée: 3. \belvis\b.*\bconcert\b 5 Daniel Tschirhart : Programmation Java V1.34 Déterminer la validité du format d’un numéro de téléphone Soit à rechercher sur une page Web les numéros de téléphone ayant le format : xxx-xxxxxxxxxx (exemple 033-0546314755). L’expression suivante permet de spécifier ce format: 4. \b\d\d\d-\d\d\d\d\d\d\d\d\d\d \d signifie tout digit, - n’a pas de signification ici en tant que méta caractère et signifie ce qu’il représente. Il est possible d’éviter la répétition des caractères \d par l’expression suivante : 5. \b\d{3}-\d{10} 6 Daniel Tschirhart : Programmation Java V1.34 Quelques méta caractères de base Nous connaissons déjà \b, \d, ., *. Le caractère \s représente n’importe quel séparateur (espace, tabulation, nouvelle ligne, …), de même \w représente n’importe que caractère alphanumérique. Exemple : \ba\w*\b recherche tous les mots commençant par le lettre a \d+ recherche tous les mots ne contenant que des chiffres (+ est identique à * sauf qu’il nécessite au moins une répétition). \b\w{6}\b trouve un mot de 6 lettres. 7 Daniel Tschirhart : Programmation Java V1.34 Syntaxe des motifs d’expression régulière La syntaxe des motifs est très riche. 1. Chaînes littérales 2. Méta caractères 3. Classes de caractères 4. Quantificateurs 5. Groupes de capture 6. Frontières de recherche 8 Daniel Tschirhart : Programmation Java V1.34 Liste des méta caractères 9 Daniel Tschirhart : Programmation Java V1.34 Méta caractères : exemples [^x] [aeiou] [a-z,A-Z] [^aeiou] T ous T ous T ous T ous caractères caractères caractères caractères sau f x aeio u m a ju scu le s et m in u scu le s sau f ae io u 10 Daniel Tschirhart : Programmation Java V1.34 Séquence d’échappement Il y a un problème lorsque que l’on cherche un caractère représentant un méta caractère comme par exemple « ^ » ou « $ ». Le caractère « \ » permet de supprimer la sémantique du méta caractère. Ainsi : « \^ », « \. », et « \\ », représentent les littéraux « ^ », « . », et « \ ». Dans une chaîne de caractère Java, le caractère « \ » est considéré comme séquence d’échappement. Ainsi : “\b“ représente le caractère de contrôle bell et “\\b“ le méta caractère \b 11 Daniel Tschirhart : Programmation Java V1.34 Répétitions * + ? Répète un nombre de fois quelconque Répète au moins une fois Répète zéro ou une fois Répète n fois {n } {n,m} Répète entre n et m fois Répète au minimum n fois {n,} 12 Daniel Tschirhart : Programmation Java V1.34 Frontières de recherche Il est souvent intéressant de forcer l’emplacement des motifs recherchés : en début de ligne, en fin de mot… Les « spécificateurs de frontière » sont résumés dans le tableau suivant : 13 Daniel Tschirhart : Programmation Java V1.34 Classes de caractères 14 Daniel Tschirhart : Programmation Java V1.34 Règles de constructions des classes de caractères personnalisées 15 Daniel Tschirhart : Programmation Java V1.34 Groupe capturant Les parenthèses permettent de regrouper les expressions. Exemple : (\d{1,3}\.){3}\d{1,3} L’expression précédente recherche 3 séquences de 1..3 digits terminés par un « . » suivi d’une autre expression de 1..3 digits. Exemple 192.168.0.1 L’expression précédente n’est cependant pas complète puisqu’elle autorise des nombres supérieurs à 255. L’expression suivante permet de corriger ce défaut. \b((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[04]\d|25[0-5]|[01]?\d\d?)\b 16 Daniel Tschirhart : Programmation Java V1.34 Quantificateurs 17 Daniel Tschirhart : Programmation Java V1.34 Mise en oeuvre des expressions régulières dans la classe String Les expressions régulières sont mises en oeuvre dans la classe String à travers les fonctions matches, replaceAll, replaceFirst, split et dans la classe Pattern à travers la fonction matches. Exemples : // éclate le string line en tableau de mots tokens String[] tokens = line.split("\\b"); // supprime dans le string word tous ce qui n'est pas caractère alphabétique minuscule. word = word.replaceAll("[^a-z]", ""); 18 Daniel Tschirhart : Programmation Java V1.34 L’API Regex de Java Java fourni dans son JDK depuis la version 1.4 une API standard permettant la manipulation d’expressions régulières. La documentation (en anglais) de cette API se trouve ici : http://java.sun.com/j2se/1.4.2/docs/api/index.html L’API doit être importée en début de fichier de définition de classe comme suit : import java.util.regex.* ; 19 Daniel Tschirhart : Programmation Java V1.34 Objets de l’API Regex Il existe deux classes : Pattern Représentation compilée d’un motif. Matcher Moteur de recherche d’un motif dans une chaîne de caractères. et une exception PatternSyntaxException Exception lancée lorsqu’une erreur apparaît dans la syntaxe des motifs employés. 20 Daniel Tschirhart : Programmation Java V1.34 Méthode matches( ) – Matcher La méthode matches() retourne vrai (true) si une chaîne vérifie un motif. Cette méthode existe dans les classes Matcher et Pattern. Objet Matcher Méthode prinpale : boolean find(); Exemple : / / compilation de la regex Pattern p = Pattern.compile("[a-z]"); / / création d’un moteur de recherche Matcher m = p.matcher("abc"); / / lancement de la recherche de toutes les occurrences boolean b = m.find(); 21 Daniel Tschirhart : Programmation Java V1.34 Exemple RegEx1 Premier exemple 22 Daniel Tschirhart : Programmation Java V1.34 Méthode split( ) La méthode split() de la classe Pattern permet de scinder une chaîne en plusieurs sous-chaînes grâce à un délimiteur défini par un motif. Le paramètre optionnel limit permet de fixer le nombre maximum de sous chaînes générées. Elle retourne un tableau de String. Syntaxe : String[ ] split(CharSequence input [, int limit] ) Exemple : / / compilation de la regex Pattern p = Pattern.compile(":"); / / séparation en sous-chaînes String[ ] items = p.split("un:deux:trois"); 23 Daniel Tschirhart : Programmation Java V1.34 Remplacements La classe Matcher offre des fonctions qui permettent de remplacer les occurrences d’un motif par une autre chaîne. Syntaxe : String replaceFirst(String replacement) String replaceAll(String replacement) Ces méthodes remplacent respectivement la première occurrence et toutes les occurrences du motif de la regex compilée associés au moteur. 24 Daniel Tschirhart : Programmation Java V1.34 Remplacements – exemple (2) Exemple complet : / / compilation de la regex avec le motif : "thé" Pattern p = Pattern.compile("thé"); / / création du moteur associé à la regex sur la chaîne "J’aime le thé." Matcher m = p.matcher("J’aime le thé."); / / remplacement de toutes les occurrences de "thé" par "chocolat" String s = m.replaceAll("chocolat"); 25 Daniel Tschirhart : Programmation Java V1.34 Exemples d'expression régulières Expression (pattern) L'expression est utilisée dans matches de la classe Pattern : boolean b = Pattern.matches(pattern, s1); ^c Recherche c en première position (ici b=false). a$ Recherche a en fin de s1 (ici b=true) coco* Le caractère précédent * peut être répéter 0..n fois. Ici on recherche coc, coco, cocoo, cocooo, …. (ici b=true) co(co)* Les caractères entre ( ) précédent * peuvent être répéter 0..n fois. Ici on recherche co, coco, cococo, cocococo,…. (ici b=true) coc+ Le caractère précédent + peut être répété 1..n fois. Ici on recherche coc, cocc, coccc,…. Affichage (ici b=true) coc? Le caractère précédent ? peut être répété 0..1 fois. Ici on recherche co, coc ici b=true) 26 Daniel Tschirhart : Programmation Java V1.34 Exemples d'expression régulières (2) Expression Commentaire o{2} La lettre o doit être représentée au moins deux fois (ici b=true) o{2,4} La lettre o doit être représentée entre deux et quatre fois (ici b=true) o..o Le point remplace n’importe quel caractère (ici b=true) Co|co Cherche Co ou co (ici b=true) c(o|a|e) Cherche co ou ca ou ce (ici b=true) [aeiou] Cherche un des caractère entre crochets (ici b=true) [^aeiou] Cherche n’importe quel caractère sauf ceux entre crochets (ici b=true) \bca \b indique le début d’un mot. Le mot doit commencer par ca (ici b=false) ca\b \b indique la fin d’un mot. Le mot doit commencer terminer par ca (ici b=true) \d Cherche un chiffre \D cherche ce qui n’est pas un chiffre 27 Daniel Tschirhart : Programmation Java V1.34 Exemples d'expression régulières (3) Expression Commentaire \w matches cherche un caractère imprimable \W matches cherche un caractère qui ne soit pas imprimable \s matches cherche un espace \S matches cherche un caractère autre qu’un espace bo(n|r) matches cherche bon ou bor bo(nj|r) matches cherche bonj ou bor bo(nj|r)* nj ou r doivent apparaître zéro ou une fois après bo. Ici on cherche bo bonj ou bor ^bo(nj|r)* Idem mais l'expression doit être en début \bbo(nj|r)+ nj ou r (précédés de bo) doivent apparaître une ou plusieurs fois en début de mot \b(bo(nj|r)+|c) matches cherche bonj ou bor ou c en début de mot 28