=encoding iso-8859-1 =head1 NAME/NOM perlrequick - Les expressions rationnelles Perl pour les impatients =head1 DESCRIPTION Ce document décrit les bases nécessaires à la compréhension, la création et l'utilisation des expressions rationnelles ou régulières (abrégé en regex) en Perl. =head1 Le guide =head2 Reconnaissance de mot simple L'expression rationnelle la plus simple est juste un mot ou, plus généralement, une chaîne de caractères. Une regex constituée d'un mot est reconnue dans (ou correspond avec) toutes les chaînes qui contiennent ce S "Salut tout le monde" =~ /monde/; # correspondance Dans cette instruction, C est la regex et les C qui l'entourent demandent à perl de rechercher une correspondance dans la chaîne. L'opérateur C<=~> applique la recherche à la chaîne placée à gauche et produit la valeur vraie si la regex correspond ou la valeur fausse sinon. Dans notre cas, C correspond au quatrième mot de C<"Salut tout le monde">. Donc l'expression est vraie. Ce concept a plusieurs usages. Des expressions de ce type sont utiles dans des S print "Correspondance\n" if "Salut tout le monde" =~ /monde/; Le sens de l'expression peut être inversé en utilisant l'opérateur CE: print "Pas de correspondance\n" if "Salut tout le monde" !~ /monde/; La chaîne littérale dans la regex peut être remplacée par une S $mot = "monde"; print "Correspondance\n" if "Salut tout le monde" =~ /$mot/; Si vous voulez chercher dans C<$_>, la partie C<$_ =~> peut être S $_ = "Salut tout le monde"; print "Correspondance\n" if /monde/; Finalement, les délimiteurs par défaut C pour une recherche de correspondance peuvent être remplacés par des délimiteurs arbitraires en les préfixant part un S :> "Salut le monde" =~ m!monde!; # correspondance, délimité par '!' "Salut le monde" =~ m{monde}; # correspondance, remarquez la paire '{}' "/usr/bin/perl" =~ m"/perl"; # correspondance après '/usr/bin', # '/' devient un caractère ordinaire Les regex doivent correspondre I à une partie de la chaîne pour être S "Salut le monde" =~ /Monde/; # pas de correspondance, casse différente "Salut le monde" =~ /e m/; # correspondance, ' ' est un caractère ordinaire "Salut le monde" =~ /monde /; # pas de correspondance, pas de ' ' à la fin La reconnaissance a lieu le plus tôt possible dans la S "Salut le monde" =~ /l/; # reconnaît le 'l' dans 'Salut "La peste est là" =~ /est/; # reconnaît le 'est' dans 'peste' Certains caractères ne peuvent être utilisés tels quels dans une regex. Ces caractères, appelés B, sont réservés pour des notations spéciales dans les expressions rationnelles. Les S {}[]()^$.|*+?\ Un meta-caractère peut-être utilisé en le préfixant par un backslash (une barre oblique inversée)E: "2+2=4" =~ /2+2/; # pas de correspondance, + est un meta-caractère "2+2=4" =~ /2\+2/; # correspondance, \+ est traité comme un + ordinaire 'C:\WIN32' =~ /C:\\WIN/; # correspondance "/usr/bin/perl" =~ /\/usr\/bin\/perl/; # correspondance Dans ce dernier exemple, le symbole divisé C est aussi préfixé par un backslash car il est utilisé comme délimiteur par l'expression rationnelle. Les caractères ASCII non affichables sont représentés par des B. Les exemples courants sont C<\t> pour une tabulation, C<\n> pour un passage à la ligne et C<\r> pour un retour chariot. Les octets quelconques sont représentés par une séquence d'échappement en octal (comme C<\033>) ou en hexadécimal (comme C<\x1B>)E: "1000\t2000" =~ m(0\t2) # correspondance "chat" =~ /\143\150\x61\x74/ # correspondance, # mais 'chat' est écrit bizarrement Les expressions rationnelles sont traitées quasiment comme des chaînes entre guillemets. Donc l'interpolation des variables S $foo = 'son'; 'caisson' =~ /cais$foo/; # correspondance 'sonnet' =~ /${foo}net/; # correspondance Dans toutes les expressions rationnelles qui précèdent, si la regex est reconnue quelque part dans la chaîne, on considère qu'il y a correspondance. Pour spécifier I doit avoir lieu la reconnaissance, vous pouvez utiliser les meta-caractères d'B C<^> et C<$>. L'ancre C<^> est reconnue au début de la chaîne alors que l'ancre C<$> est reconnue à la fin de la chaîne ou juste avant une fin de ligne à la fin de la chaîne. Quelques S "housekeeper" =~ /keeper/; # correspondance "housekeeper" =~ /^keeper/; # pas de correspondance "housekeeper" =~ /keeper$/; # correspondance "housekeeper\n" =~ /keeper$/; # correspondance "housekeeper" =~ /^housekeeper$/; # correspondance =head2 Utilisation des classes de caractères Une B définit un ensemble de caractères acceptables en un point particulier de l'expression rationnelle. Une classe de caractères s'exprime par une paire de crochets C<[...]> contenant l'ensemble des caractères acceptables. Voici quelques S /rame/; # reconnaît 'rame' /[clr]ame/; # reconnaît 'came, 'lame' ou 'rame' "abc" =~ /[cab]/; # reconnaît 'a' Dans la dernière instruction, bien que C<'c'> soit le premier caractère de la classe, le premier endroit où cette expression rationnelle peut être reconnue est le C<'a'>. /[oO][uU][iI]/; # reconnaît 'oui' indépendamment de la casse # 'oui', 'Oui', 'OUI', etc. /oui/i; # reconnaît aussi 'oui' indépendamment de la casse Le dernier exemple démontre l'usage du modificateur C<'i'> qui permet une mise en correspondance indépendante de la casse (majuscule/minuscule). Les classes de caractères ont elles aussi leurs caractères normaux et spéciaux mais ce ne sont pas les mêmes qu'à l'extérieur d'une classe. Les caractères spéciaux sont C<-]\^$>. Pour les rendre normaux, il faut les préfixer par C<\>E: /[\]c]def/; # correspond à ']def' ou 'cdef' $x = 'clr'; /[$x]ame/; # correspond à 'came, 'lame' ou 'rame' /[\$x]ame/; # correspond à '$ame' or 'xame' /[\\$x]ame/; # correspond à '\ame', 'came, 'lame' ou 'rame' Le caractère spécial C<'-'> agit à l'intérieur d'une classe comme un opérateur d'intervalle. Donc les classes peu maniables C<[0123456789]> et C<[abcde...xyz]> deviennent C<[0-9]> et C<[a-z]>E: /item[0-9]/; # reconnaît 'item0' ou 'item1' ... ou 'item9' /[0-9a-fA-F]/; # reconnaît un chiffre hexadécimal Si C<'-'> est le premier ou le dernier caractère d'une classe de caractères, il est traité comme un caractère ordinaire. Le caractère C<^> est spécial en première position de la classe. Il indique alors une B qui reconnaît tous les caractères sauf ceux présents entre les crochets. Qu'elle soit de la forme C<[...]> ou C<[^...]>, une classe de caractères doit correspondre à un caractère sinon la reconnaissance échoue. S /[^a]at/; # ne reconnaît ni 'aat' ni 'at', mais reconnaît # 'bat', 'cat, '0at', '%at', etc. /[^0-9]/; # reconnaît un caractère non numérique /[a^]at/; # reconnaît 'aat' ou '^at'; dans ce cas '^' est ordinaire Perl propose plusieurs abréviations pour des classes de caractères S =over 4 =item * \d est un chiffre et est équivalent à [0-9] =item * \s est un blanc et est équivalent à [\ \t\r\n\f] =item * \w est caractère I (alphanumérique ou _) et est équivalent à [0-9a-zA-Z_] =item * \D est la négation de \d; il représente tout autre caractère qu'un chiffre [^0-9] =item * \S est la négation de \s [^\s] =item * \W est la négation de \w [^\w] =item * Le point '.' reconnaît n'importe quel caractère sauf "\n". =back Les abréviations C<\d\s\w\D\S\W> peuvent être utilisées à l'extérieur ou à l'intérieur d'une classe de caractères. Quelques S /\d\d:\d\d:\d\d/; # reconnaît une heure au format hh:mm:ss /[\d\s]/; # reconnaît un chiffre ou un blanc /\w\W\w/; # reconnaît un caractère mot suivi d'un caractère # non mot, suivi d'un caractère mot /..rt/; # reconnaît deux caractères quelconques suivis de 'rt' /fin\./; # reconnaît 'fin.' /fin[.]/; # idem, reconnaît 'fin.' L'ancre C<\b> est reconnue à la limite de S entre un caractère mot et un caractère non mot (entre C<\w\W> ou entre C<\W\w>). $x = "Housecat catenates house and cat"; $x =~ /\bcat/; # reconnaît cat dans 'catenates' $x =~ /cat\b/; # reconnaît cat dans 'housecat' $x =~ /\bcat\b/; # reconnaît 'cat' en fin de chaîne Dans le dernier exemple, la fin de la chaîne est considérée comme une limite de mot. =head2 Reconnaître ceci ou cela Nous pouvons reconnaître différentes chaînes grâce au meta-caractère d'alternative C<|>. Pour reconnaître C ou C, nous pouvons utiliser la regex C. Comme précédemment, perl essayera de reconnaître la regex le plus tôt possible dans la chaîne. À chaque position, perl essayera la première S C. Si C ne correspond pas, perl essayera la possibilité S C. Si C ne convient pas non plus alors il n'y a pas correspondance et perl se déplace à la position suivante dans la chaîne. Quelques S "chiens et chats" =~ /chien|chat|rat/; # reconnaît "chien" "chiens et chats" =~ /chat|chien|rat/; # reconnaît "chien" Bien que C soit la première possibilité dans la seconde regex, C est reconnue plus tôt dans la chaîne. "chat" =~ /c|ch|cha|chat/; # reconnaît "c" "chat" =~ /chat|cha|ch|c/; # reconnaît "chat" En une position donnée, la possibilité qui est retenue est la première qui permet la reconnaissance de l'expression. Ici, toute les possibilités correspondent dès le premier caractère donc c'est la première qui est retenue. =head2 Groupement et hiérarchie Les meta-caractères de regroupement C<()> permettent de traiter une partie d'une regex comme une seule entité. Une partie d'une regex est groupée en l'entourant de parenthèses. L'expression C peut reconnaître C suivi soit de C soit de C. D'autres S /(a|b)b/; # reconnaît 'ab' ou 'bb' /(^a|b)c/; # reconnaît 'ac' au début de la chaîne ou 'bc' n'importe où /chat(on|)/; # reconnaît 'chaton' ou 'chat'. /chat(on(s|)|)/; # reconnaît 'chatons' ou 'chaton' ou 'chat'. # Notez que les groupes peuvent être imbriqués "20" =~ /(19|20|)\d\d/; # reconnaît la possibilité vide '()\d\d', # puisque '20\d\d' ne peut pas correspondre =head2 Mémorisation de la correspondance Les meta-caractères de regroupement C<()> permettent aussi la mémorisation de la partie reconnue de la chaîne. Pour chaque groupe, la partie reconnue de la chaîne va dans une variable spéciale C<$1> ou C<$2>, etc. Elles peuvent être utilisées comme des variables S # extraction des heures, minutes, secondes $temps =~ /(\d\d):(\d\d):(\d\d)/; # reconnaît le format hh:mm:ss $heures = $1; $minutes = $2; $secondes = $3; Dans un contexte de liste, une mise en correspondance C avec regroupement retourne la liste des valeurs C<($1, $2, ...)>. Nous pouvons donc S<écrire :> ($heures, $minutes, $secondes) = ($temps =~ /(\d\d):(\d\d):(\d\d)/); Si les regroupements sont imbriqués, C<$1> sera le groupe ayant la parenthèse ouvrante la plus à gauche, C<$2> celui ayant la parenthèse ouvrante suivante, etc. Voici une expression rationnelle complexe avec les numéros des variables de groupes indiqués S /(ab(cd|ef)((gi)|j))/; 1 2 34 Les références arrières C<\1>, C<\2>... sont associées aux variables C<$1>, C<$2>... Les références arrières sont utilisées I l'expression rationnelle S /(\w\w\w)\s\1/; # trouve les séquences telles que 'les les' dans la chaîne C<$1>, C<$2>... ne devraient être utilisé qu'à l'extérieur de l'expression tandis que C<\1>, C<\2> ne devraient l'être qu'à l'intérieur. =head2 Répétitions et quantificateurs Les meta-caractères ou quantificateurs C, C<*> et C<{}> nous permettent de fixer le nombre de répétitions d'une portion de regex. Un quantificateur est placé juste après le caractère, la classe de caractères ou le regroupement à répéter. Ils ont le sens S =over 4 =item * C : reconnaît 'a' zéro ou une fois. =item * C : reconnaît 'a' zéro fois ou plus. =item * C : reconnaît 'a' au moins une fois. =item * C : reconnaît 'a' au moins C fois, mais pas plus de C fois. =item * C : reconnaît 'a' au moins C fois. =item * C : reconnaît 'a' exactement C fois. =back Voici quelques S /[a-z]+\s+\d*/; # reconnaît un mot en minuscules suivi d'au moins un blanc # et éventuellement d'un certain nombre de chiffres /(\w+)\s+\1/; # reconnaît la répétition d'un mot de longueur quelconque $annee =~ /\d{2,4}/; # s'assure que l'année contient au moins 2 chiffres et # pas plus de 4 chiffres $annee =~ /\d{4}|\d{2}/; # meilleure reconnaissance; exclut le cas de 3 chiffres Ces quantificateurs essayent d'entrer en correspondance avec la chaîne la plus longue possible tout en permettant à la regex d'être reconnue (ils sont gourmands). S $x = 'Ce chien est le mien'; $x =~ /^(.*)(ien)(.*)$/; # correspondance, # $1 = 'Ce chien est le m' # $2 = 'ien' # $3 = '' (aucun caractère) Le premier quantificateur C<.*> consomme la chaîne la plus longue possible tout en laissant une possibilité de correspondance pour la regex globale. Le second quantificateur C<.*> n'a plus de caractère disponible donc il est reconnu zéro fois. =head2 Plus de correspondances Il y a encore quelques détails que vous devez connaître à propos des opérateurs de correspondance. Dans le code $motif = 'Seuss'; while (<>) { print if /$motif/; } perl doit réévaluer C<$motif> à chaque passage dans la boucle. Si C<$motif> ne change jamais, utilisez le modificateur C pour n'effectuer qu'une seule fois l'interpolation. Si vous ne voulez aucune interpolation, utilisez les délimiteurs spéciaux CE: @motif = ('Seuss'); m/@motif/; # reconnaît 'Seuss' m'@motif'; # reconnaît la chaîne littérale '@motif' Le modificateur C demande à l'opérateur de mise en correspondance de s'appliquer à une chaîne autant de fois que possible. Dans un contexte scalaire, une recherche de correspondance assortie du modificateur C sautera de reconnaissance en reconnaissance en se souvenant à chaque fois de l'endroit où elle s'est arrêtée la fois précédente. Vous pouvez récupérer la position atteinte via la fonction C. Par S $x = "chien chat maison"; # 3 mots while ($x =~ /(\w+)/g) { print "le mot $1 se termine en ", pos $x, "\n"; } affiche le mot chien se termine en 5 le mot chat se termine en 10 le mot maison se termine en 17 L'échec de la reconnaissance ou la modification de la chaîne réinitialise la position. Si vous ne voulez pas de réinitialisation en cas d'échec, ajoutez le modificateur C comme dans C. Dans un contexte de liste, C retournera la liste complète des groupes reconnus ou, si il n'y a pas de regroupement, la liste des sous-chaînes reconnues par la regex complète. S @mots = ($x =~ /(\w+)/g); # correspondance, # $mots[0] = 'chien' # $mots[1] = 'chat' # $mots[2] = 'maison' =head2 Recherche et remplacement On effectue une recherche et remplacement en utilisant C. C est comme une chaîne Perl entre guillemets qui remplacera dans la chaîne la partie reconnue par la C. Là aussi, l'opérateur C<=~> permet de choisir à quelle chaîne sera appliquée C. Si C doit s'appliquer à C<$_>, il est possible d'omettre S>. S'il y a une correspondance, C retourne le nombre de remplacements effectués sinon il retourne faux. Voici quelques S $x = "Time to feed the cat!"; $x =~ s/cat/hacker/; # $x contient "Time to feed the hacker!" $y = "'quoted words'"; $y =~ s/^'(.*)'$/$1/; # supprime les apostrophes, # $y contient "quoted words" Lorsqu'on utilise l'opérateur C, les variables C<$1>, C<$2>, etc. sont directement utilisables dans l'expression de remplacement. Avec le modificateur C, la recherche et remplacement auront lieu sur toutes les occurrences de l'expression S $x = "I batted 4 for 4"; $x =~ s/4/four/; # $x contient "I batted four for 4" $x = "I batted 4 for 4"; $x =~ s/4/four/g; # $x contient "I batted four for four" Le modificateur d'évaluation C ajoute un C autour de la chaîne de remplacement et c'est le résultat de cette évaluation qui sera substitué à la sous-chaîne reconnue. S # inverser tous les mots d'une chaîne $x = "the cat in the hat"; $x =~ s/(\w+)/reverse $1/ge; # $x contient "eht tac ni eht tah" # convertir un pourcentage en fraction $x = "A 39% hit rate"; $x =~ s!(\d+)%!$1/100!e; # $x contient "A 0.39 hit rate" Le dernier exemple montre que C peut utiliser d'autres délimiteurs tels que C ou C... ou même C. Si les délimiteurs sont des apostrophes C alors l'expression rationnelle et la chaîne de remplacement sont considérées comme des chaînes entre apostrophes (pas d'interpolation des variables). =head2 L'opérateur de S split C découpe C en une liste de sous-chaînes et retourne cette liste. La regex détermine la séquence de caractères à utiliser comme séparateur lors du découpage de C. Par exemple, pour découper une chaîne en mots, S $x = "Calvin and Hobbes"; @mots = split /\s+/, $x; # $mots[0] = 'Calvin' # $mots[1] = 'and' # $mots[2] = 'Hobbes' Pour extraire une liste de nombres séparés par des S $x = "1,618;2,718; 3,142"; @const = split /;\s*/, $x; # $const[0] = '1,618' # $const[1] = '2,718' # $const[2] = '3,142' Si vous utilisez l'expression rationnelle vide C, la chaîne est découpée en ses caractères. Si l'expression rationnelle contient des regroupements alors la liste produite contiendra aussi les groupes S $x = "/usr/bin"; @parts = split m!(/)!, $x; # $parts[0] = '' # $parts[1] = '/' # $parts[2] = 'usr' # $parts[3] = '/' # $parts[4] = 'bin' Puisque le premier caractère de $x est reconnu comme délimiteur, C ajoute un élément vide au début de la liste. =head1 BUGS Aucun. =head1 VOIR AUSSI C'est un simple guide d'introduction. Pour un tutoriel plus complet voir L et pour une référence complète voir L. =head1 AUTEUR ET COPYRIGHT Copyright (c) 2000 Mark Kvale All rights reserved. This document may be distributed under the same terms as Perl itself. Tous droits réservés. Ce document peut être distribuer sous les mêmes termes que Perl. =head2 Remerciements L'auteur tient à remercier Mark-Jason Dominus, Tom Christiansen, Ilya Zakharevich, Brad Hughes et Mike Giroux pour leurs commentaires précieux. =head1 TRADUCTION =head2 Version Cette traduction française correspond à la version anglaise distribuée avec perl 5.8.5. Pour en savoir plus concernant ces traductions, consultez L. =head2 Traducteur Paul Gaborit (Paul.Gaborit at enstimac.fr). =head2 Relecture Aucune pour l'instant. =cut