SELFHTML/Quickbar CGI/Perl Eléments de langage Perl


Expressions régulières

Cette page est un document avec du texte et des informations Généralités sur les expressions régulières
Appliquer des expressions régulières
Expressions régulières pour signes distincts
Expressions régulières pour chaînes de caractères 
Expressions régulières avec alternatives
Ordre de priorité des parenthèses dans les expressions régulières
Expressions partielles avec parenthèses
 

Généralités sur les expressions régulières

Les expressions régulières sont pour les signes et les chaînes de caractères des modèles de recherche précisément définis. À l'aide de ces modèles de recherche, vous pouvez par exemple parcourir et traiter le contenu de variables. Pour les travaux CGI, les expressions régulières sont d'une importance capitale. Le flux de données d'un formulaire HTML transmis à un programme CGI lors de l'envoi du formulaire, peut, à l'aide d'expressions régulières, être par exemple décomposé dans ses différentes parties constituantes. De même vous pouvez à l'aide d'expressions régulières lors de la lecture de fichiers (par exemple un fichier avec les enregistrements d'un livre de visites) et au vu des conventions d'après lesquelles le fichier est construit, lire les différents enregistrements dans l'ordre et les transmettre sous forme de code HTML au navigateur WWW qui appelle. Et enfin les expressions régulières sont un moyen puissant pour rechercher des expressions de recherche complexes dans des bases de données importantes.

Les expressions régulières sont sans doute très inhabituelles pour les débutants et c'est la raison principale pour laquelle on trouve dans certains scripts Perl des chaînes de caractères assez étranges qu'on pourrait croire cryptées. En revanche, celui qui a l'habitude de la commande Unix grep, comprendra immédiatement avec les expressions régulières en Perl.

 

Appliquer des expressions régulières

Pour appliquer des expressions régulières, vous devez savoir quelles possibilités elles offrent.

Exemple 1:

#!/usr/bin/perl

$donnees = $ENV{'PATH'};
if($donnees =~ /PERL/)    # Est-ce qu'on y trouve la chaîne de caractères 'PERL' ?
 { print "Ah, PERL se trouve dans votre variable PATH !\n"; }
else   
 { print "PERL ne se trouve malheureusement pas dans votre variable PATH!\n"; }

Exemple 2:

#!/usr/bin/perl

@villes = ("Berlin","Paris","London","Madrid","Athènes","Rome","Lisbonne","Stockholm","Kingston");

for(@villes)
 {
  if(/[MKS]/)   # Toutes les villes dans le nom desquelles on trouve 'M', 'K' ou 'S' 
   { print "La ville ", $_, " correspond au modèle de recherche \n"; }
 }

Exemple 3:

#!/usr/bin/perl

open(FICHIERLOG,"<access.log");
$acces = 0;

while(<FICHIERLOG>)
 {
  /index.htm/ ? $acces = $acces + 1 : $acces = $acces;
 }
print $acces, " accès au fichier index.htm!\n";
close(FICHIERLOG);

Explication:

Vous reconnaissez normalement une expression régulière à deux barres obliques /.../. Entre les barres obliques est placée l'expression régulière respective.

Si vous voulez mettre en oeuvre une expression régulière, vous avez d'abord besoin de quelque chose que vous voulez rechercher. Ce peut être par exemple la valeur sauvegardée dans une variable scalaire simple, comme dans l'exemple 1 ci-dessus, ou les valeurs qui se trouvent dans les éléments d'une liste, comme dans l'exemple 2 ci-dessus ou aussi les différentes lignes d'un fichier comme dans l'exemple 3 ci-dessus.

Dans l'exemple 1, la chaîne de caractères "PERL" est recherchée dans la variable d'environnement PATH. Observez qu'une telle chaîne de caractères dans une expression régulière est notée sans guillemets. Dans l'exemple le contenu de $ENV{'PATH'} est sauvegardé dans une variable scalaire simple $donnees. Avec if($donnees =~ /PERL/) la valeur de cette variable scalaire simple est parcourue pour rechercher la chaîne de caractères "PERL". Ici, l'opérateur de requête =~ est important. Avec des expressions If du genre if($nomvariable =~ /expression.reg/) vous pouvez donc parcourir des variables scalaires simple de votre choix à la recherche de contenus de votre choix.

Dans l'exemple 2 est définie une liste contenant des noms de ville. Dans la boucle for Tous les éléments de la liste, c'est à dire, tous les noms de ville, sont parcourus pour rechercher si l'une des majuscules M, K ou S s'y trouve. La recherche est formulée avec if(/[MKS]/). Dans ce cas, à la différence de l'exemple 1, aucun opérateur de requête n'est mis en oeuvre. La requête se réfère bien, grâce à la boucle, à l'élément actuel de la liste. Vous pourriez noter la requête également avec la variable prédéfinie $_sous la forme if($_ =~ /[MKS]/). Étant donné qu'il est clair que c'est de cette valeur qu'il s'agit, la forme abrégée if(/[MKS]/)suffit.

Dans l'exemple 3, un fichier log est lu ligne par ligne. Dans ce fichier est recherchée l'existence de "index.htm". Si une ligne contenant cette chaîne de caractères est trouvée, un compteur d'accès est incrémenté, sinon le compteur d'accès reste inchangé. À la fin, le nombre d'accès à index.htm ainsi recherché est sorti. L'expression régulière de cette exemple se trouve dans une simple requête soit..soit. L'évaluation de l'expression régulière dans ce cas est simplement de savoir si elle est vraie ou fausse. Si elle est vraie (si "index.htm" se trouve dans la ligne actuelle), l'instruction à gauche des deux points est exécutée. Si elle est fausse, l' expression à droite des deux points est exécutée.
(À ce sujet, voyez aussi lire et écrire les fichiers).

Attention:

Un domaine d'application important pour les expressions régulières est aussi constitué par la recherche et le remplacement de chaînes de caractères. Des expressions régulières peuvent en outre se trouver dans quelques fonctions Perl comme paramètres à transmettre.

 

Expressions régulières pour signes distincts

Vous pouvez

Les exemples suivants sont numérotés, par exemple avec (1). Ces numéros ne font pas partie des expressions régulières, ils ne servent que de repères pour les explications se rapportant aux exemples.

Exemples:

( 1) /a/                 # trouve 'a'
( 2) /[ab]/              # trouve 'a' ou 'b'
( 3) /[A-Z]/             # trouve les majuscules
( 4) /[0-9]/             # trouve les chiffres
( 5) /\d/                # trouve les chiffres- exactement comme ( 4)
( 6) /\D/                # trouve tout sauf les chiffres
( 7) /[0-9]\-/           # trouve les chiffres ou les signes moins
( 8) /[\[\]]/            # trouve tout ce qui contient des crochets
( 9) /[a-zA-Z0-9_]/      # trouve les lettres, les chiffres ou les tirets de soulignement
(10) /[\w]/              # trouve les lettres, les chiffres ou les tirets de soulignement - exactement comme ( 9)
(11) /[\W]/              # trouve tout sauf les lettres, les chiffres ou les tirets de soulignement
(12) /[\r]/              # trouve le caractère de contrôle pour le retour chariot (typique au DOS)
(13) /[\n]/              # trouve le caractère de contrôle pour avance d'une ligne
(14) /[\t]/              # trouve le caractère de contrôle pour le tabulateur 
(15) /[\f]/              # trouve le caractère de contrôle pour avance feuille
(16) /[\s]/              # trouve les espaces et les caractères de contrôle de (12-15) 
(17) /[\S]/              # trouve tout sauf les espaces et les caractères de contrôle de (12-15) 
(18) /[^éèàùêâûÉÈàÊ]/    # trouve tout ce qui ne contient pas d'accent
(19) /[^a-zA-Z]/         # trouve tout ce qui ne contient pas de lettres
(20) /[ab]/s             # trouve 'a' ou 'b' même au delà les limites de la ligne

Explication:

Quand vous devez chercher différents signes dans une expression régulière, vous devez mettre l'expression recherchée entre des barres obliques et inclure le tout entre crochets. Il n'y a que si vous recherchez des caractères distincts comme dans l'exemple 1 que vous pouvez omettre les crochets. Si vous notez plusieurs signes sans les crochets, ceux-ci sont interprétés comme chaîne de caractères.

Si vous voulez rechercher un groupe de signes déterminés, notez les simplement entre crochets comme dans l'exemple (2).

Si vous voulez rechercher des étendues de signes, par exemple des lettres de la première moitié de l'alphabet ou des chiffres, désignez le passage désiré par le signe de départ, un signe moins comme trait d'union et le signe de fin comme dans les exemples (3) et (4).

Si vous recherchez un des signes +-?.*^$()[]{}|\ notez devant le signe une barre oblique inversée \, comme dans les exemples (7) et (8).

Il y a quelques modèles de recherche particuliers, constitués par une barre oblique inversée et par une lettre code. Les exemples (5)/(6), (10) jusqu'à (17) montrent ces modèles de recherche.

Vous pouvez aussi effectuer une recherche négative. Pour cela notez l'accent circonflexe ^ devant le signe et le passage de signes désiré. Une telle recherche fait en sorte que seuls seront trouvés les endroits qui ne contiennent pas les signes mentionnés. Les exemples (18) et (19) en sont des exemples d'application.

Pour une recherche sur plusieurs lignes, vous devez noter derrière la barre oblique de fermeture un s - voyez l'exemple (20).

 

Expressions régulières pour chaînes de caractères

Vous pouvez

Les exemples suivants sont numérotés, par exemple avec (1). Ces numéros ne font pas partie des expressions régulières, ils ne servent que de repères pour les explications se rapportant aux exemples.

Exemples:

( 1) /aus/          # trouve 'aus' - même dans 'chaussée' ou   'Gauss'
( 2) /aus?/         # trouve 'aus' etc. - mais aussi 'au' et 'aut'
( 3) /a./           # trouve 'as' et 'an'
                    # (quelconque autre signe derrière 'a')
( 4) /a+/           # trouve 'a' et 'aa' et 'aaaaa'
                    # (une ou un nombre quelconque de lettres 'a')
( 5) /a*/           # trouve 'a' und 'aa' und 'aaaaa' und 'b'
                    # (pas de ou un nombre quelconque de lettres 'a')
( 6) /Ge.s/         # trouve 'Gers' et 'Gets' mais pas 'Genes'
( 7) /Ge.+s/        # trouve 'Gers' et 'Gets' et 'Genes'
                    # (un signe quelconque ou un nombre quelconque de signes quelconques)
( 8) /Ge.s/         # trouve 'Gers' et 'Gets' mais pas 'Gene'
( 9) /Ge.?s/        # trouve 'Gers' et 'Gets' et 'Gene'
(10) /x{10,20}/     # trouve entre 10 et 20 'x' à la suite
(11) /x{10,}/       # trouve 10  'x' et plus à la suite
(12) /x.{2}y/       # trouve seulement 'xxxy'
(13) /Jean\b/       # trouve 'Jean' mais pas 'Jeannot'
(14) /\bvers/       # trouve 'verser' ou 'versatile' mais pas 'envers'
(15) /\baus\b/      # trouve 'vers' mais pas 'envers' ni 'verser'
(16) /\baus\B/      # trouve 'verser' mais ni 'vers' et ni 'envers'
(17) /^Jean/        # trouve 'Jean' seulement au début du passage à parcourir
(18) /Jean$/        # trouve 'Jean' seulement à la fin du passage à parcourir
(19) /^\s*$/        # trouve les lignes ne comprenant que des espaces ou similaire
(20) /$Nom/         # trouve le contenu de la variable scalaire simple $Nom
(21) /aus/s         # trouve 'aus' même au delà les limites de la ligne

Explication:

Quand vous voulez rechercher une certaine chaîne de caractères dans une expression régulière, notez simplement la chaîne de caractères entre les deux barres obliques de l'expression régulière comme dans l'exemple (1).

Il y a pour les expressions régulières différents "opérateurs de groupage". Associés les uns aux autres ou utilisés dans des expressions plus compliquées, vous pouvez grâce aux opérateurs de groupage effectuer des recherches avec jokers:
Le point . est placé pour exactement un signe quelconque à l'endroit concerné - voyez à ce sujet l'exemple (3). Si vous venez de l'univers DOS/Windows: le point d'une expression régulière y correspond au joker point d'interrogation, par exemple pour les noms de fichier.
Le point d'interrogation ? par contre signifie dans une expression régulière: le signe avant le point d'interrogation ou non. voyez à ce sujet l'exemple (2).
Le signe plus + signifie: une ou plusieurs répétitions du signe placé avant le signe plus. voyez à ce sujet l'exemple (4).
Le signe étoile * signifie: pas de, une ou plusieurs répétitions du signe placé avant l'étoile. voyez à ce sujet l'exemple (5).
Si vous notez un point (qui remplace un signe quelconque) avant le signe plus + ou *, vous obtenez un joker qui correspond à l'astérisque * dans l'univers DOS/Windows, par exemple pour les noms de fichiers. voyez à ce sujet les exemples (6) à (9).
Les parenthèses accolades avec un ou deux nombres n qui y sont placés {n} signifient n répétitions du signe placé avant les parenthèses accolades à l'endroit concerné - voyez à ce sujet les exemples (10) à (12). Si vous notez un point avant les parenthèses accolades, la mention dans les parenthèses accolades signifie autant de signes quelconques que mentionné - voyez à ce sujet l'exemple (12).

Vous pouvez rechercher des chaînes de caractères qui ne seront trouvées que si elles se trouvent au début ou à la fin d'un mot. Même l'inverse est possible: Vous pouvez rechercher des chaînes de caractères qui ne seront trouvées que si elles ne se trouvent pas au début ou pas à la fin d'un mot.
Avec \b avant une chaîne de caractères, la chaîne de caractères ne sera trouvée que si elle se trouve au début d'un mot.
Avec \b après une chaîne de caractères, la chaîne de caractères ne sera trouvée que si elle se trouve à la fin d'un mot.
Avec \B avant une chaîne de caractères, la chaîne de caractères ne sera trouvée que si elle ne se trouve pas au début d'un mot.
Avec \B après une chaîne de caractères, la chaîne de caractères ne sera trouvée que si elle ne se trouve pas à la fin d'un mot.
Concernant ces possibilités voyez les exemples (13) à (16).

Vous pouvez rechercher des chaînes de caractères qui ne seront trouvées que si elles se trouvent au début ou à la fin d'une ligne dans le passage à parcourir. Ce qui est avant tout intéressant en relation avec des lignes dans des fichiers texte.
Avec l'accent circonflexe ^ au début de l'expression recherchée, la chaîne de caractères ne sera trouvée que si elle est au début d'une ligne.
Avec le signe Dollar $ à la fin de l'expression recherchée, la chaîne de caractères ne sera trouvée que si elle est à la fin d'une ligne.
Concernant les possibilités voyez les exemples (17) à (19).

Vous pouvez également employer des variables à l'intérieur d'expressions régulières. Par ce moyen, vous pouvez utiliser des données dynamiques comme critères de recherche. En relation avec CGI vous pourriez par exemple prendre comme critère de recherche l'entrée de l'utilisateur dans un champ de formulaire. Voyez à ce sujet l'exemple (20).

Pour des recherches sur plusieurs lignes, vous devez noter un s derrière la dernière barre oblique - voir à ce sujet l'exemple (21).

 

Expressions régulières avec alternatives

Vous pouvez noter plusieurs critères de recherche. Tous les endroits, dans lesquels se trouve au moins un des critères de recherche, seront alors trouvés.

Exemples:

/a|b/          # trouve 'a' ou 'b' - identique à /[ab]/
/de|sang/      # trouve 'de' et 'depuis' mais aussi 'sang' et 'sangsue'

Explication:

Séparez les alternatives avec le signe |. Dans le premier des exemples ci-dessus est formulée une alternative avec deux signes distincts. Ceci n'est cependant utilisé que rarement, étant donné que la façon d'écrire /[ab]/, qui signifie la même chose, est plus courante pour le faire.
Dans le deuxième des exemples sont recherchées deux chaînes de caractères différentes. Chaque endroit contenant l'une des chaînes de caractères compte comme occurrence. Vous pouvez bien sûr noter plus de deux possibilités.
Pour les différentes alternatives sont permises toutes les autres possibilités des expressions régulières.

 

Ordre de priorité des parenthèses dans les expressions régulières

Les signes particuliers dans les expressions régulières sont évaluées par l'interpréteur Perl dans un certain ordre de priorité.

  1. rang: () (parenthèses)
  2. rang: + * ? {#,#} (opérateurs de groupage)
  3. rang: abc ^ $ \b \B (signes/chaînes de caractères, début/fin de ligne, début/fin de mot)
  4. rang: | (alternative)

Grâce à cet ordre, chaque expression régulière peut être évaluée sans équivoque. Si cependant vous désirez que l'évaluation d'une expression se fasse autrement que suivant l'ordre établi, vous pouvez utiliser des parenthèses dans l'expression pour imposer une évaluation différente.

Exemples:

/a|bc|d/       # trouve 'a' ou 'bc' ou 'd'
/(a|b)(c|d)/   # trouve 'ac' ou 'ad' ou 'bc' ou 'bd'

Explication:

D'après l'ordre de priorité, les signes ou chaînes de caractères ont priorité sur les signes de séparation entre alternatives. À l'aide de parenthèses, vous pouvez imposer une évaluation différente (voir exemple).

 

Expressions partielles avec parenthèses

Pour des expressions régulières complexes, vous pouvez à l'aide de parenthèses sauvegarder des parties distinctes de l'expression régulière pour la référencer plus tard à un autre endroit.

Exemple:

#!/usr/bin/perl

$phrase = "Que peut donc bien faire l'homme avec la femme là sous la couette?";
if($phrase =~ /(\bla\b).*\1/)
 { print $1; }

Explication:

Dans l'exemple est vérifié si dans $phrase le mot 'la' figure plus d'une fois.

Pour cela, ce que l'ont veut chercher en réalité est mis entre parenthèses. Dans l'exemple, c'est le mot distinct 'la' qui doit être recherché, c'est pourquoi la formulation dans l'expression régulière est: \bla\b. Cette expression partielle est mise entre parenthèses. C'est ce qui permet à l'interpréteur Perl de remarquer cette expression partielle. Derrière, l'instruction .* suit: Après le mot 'la' peut suivre n'importe quoi. La syntaxe \1 référence finalement la parenthèse définie auparavant. Ce qui veut dire: si l'interpréteur Perl trouve le mot 'la', il vérifie si le mot a déjà été trouvé une fois.
Si vous avez deux parenthèses similaires ou plus dans une expression régulière, vous pouvez référencer ces parenthèses avec \1, \2, \3 etc. Pour cela il existe en Perl des variables préfinies correspondantes, à savoir $1, $2, $3 etc...

La sortie print $1 de l'exemple ci dessus sort le contenu de $1. Dans l'exemple, c'est le mot 'la' qui y est sauvegardé, mais uniquement parce qu'il y a plus d'une occurrence dans la phrase.

 
après: Caractères de contrôle et notations particulières
avant: Opérateurs
 

SELFHTML/Quickbar CGI/Perl Eléments de langage Perl

© 1998 Stefan Münz / © 2001 Traduction  Serge François, 13405@free.fr