Source de cours/regexp.php

<?
  
require ("../page.inc");
  require (
"lessons.inc");
  
  
$currentPage = new LessonPage("regexp");

$currentPage->setContent('');

  
$currentPage->addChapter('general''Généralités''
<p>
Une expression régulière (appelée aussi <strong>expression rationnelle</strong>) est une chaîne de caractères contenant un motif qui peut ensuite être utilisé pour une recherche par exemple. Nombre de logiciels Unix les utilisent, c\'est pour cela qu\'il est nécessaire de les connaître.
</p><p>
Pour la suite, on utilisera la notation du langage Perl (par simple convention). <strong>=~</strong> indiquera qu\'une chaîne placée à gauche de ce signe correspond à une expression régulière placée à droite. A l\'inverse <strong>!~</strong> sera utilisé lorsqu\'elle ne correspond pas (c\'est-à-dire qu\'elle ne contient pas l\'expression régulière). Les chaînes et expressions régulières seront placées entre doubles guillemets.
</p><p>
L\'expression régulière la plus simple est un mot. Toute phrase contenant ce mot correspondra à ce motif. Exemples&nbsp;:
</p>
<code>
"ceci est une phrase" =~ "est"<br />
"nord sud est ouest" =~ "est"<br />
"ceci était une phrase" !~ "est"<br />
</code>
<p>
On peut imposer que le motif soit en début ou en fin de chaîne avec respectivement <strong>^</strong> et <strong>$</strong>
</p>
<code>
"est nord sud ouest" =~ "^est"<br />
"nord sud ouest est" =~ "est$"<br />
"nord sud est ouest" !~ "est$"<br />
</code>
<p>
On peut rechercher sur plusieurs motifs en même temps en utilisant le symbole <strong>|</strong> pour les séparer. Il se lit comme un <strong>OU logique</strong>.
</p>
<code>
"est" =~ "est|nord"<br />
"nord" =~ "est|nord"<br />
"sud" !~ "est|nord"<br />
</code>
<p>
Doivent être présents soit la chaîne "est" soit la chaîne "nord".
</p>
'
);

  
$currentPage->addChapter('quanti''Quantificateurs''
<p>
On peut spécifier le nombre de fois qu\'un caractère doit apparaître à l\'aide des <strong>quantificateurs</strong>. Il en existe 3 et tous se rapportent au caractère le précédant. Le <strong>?</strong> indique que celui-ci peut être répété 0 ou 1 fois. Le <strong>+</strong> au moins 1 fois. Et enfin le <strong>*</strong> 0 ou plusieurs fois. Exemples&nbsp;:
</p>
<code>
"et" =~ "es?t"<br />
"est" =~ "es?t"<br />
"esst" !~ "es?t"<br />
<br />
"et" !~ "es+t"<br />
"est" =~ "es+t"<br />
"esst" =~ "es+t"<br />
<br />
"et" =~ "es*t"<br />
"est" =~ "es*t"<br />
"esst" =~ "es*t"<br />
</code>
<p>
On peut aussi spécifier un nombre explicite de fois où un caractère doit être présent. Cela se fait à l\'aide des <strong>accolades { }</strong> entourant les nombres de répétitions maximal et minimal séparés par une virgule. Certains outils comme grep nécessitent que ces accolades soient précédées par un <strong>\</strong> (anti-slash).
</p>
<code>
"est" =~ "es{0,2}t"<br />
"essst" !~ "es{0,2}t"<br />
</code>
<p>
Cette expression serait notée comme suit avec grep&nbsp;:
</p>
<code>
"es\{0,2\}t"<br />
</code>
<p>
Elle indique qu\'il doit y avoir entre 0 et 2 fois le caractère s (les bornes sont incluses). La borne supérieure peut être omise pour indiquer par exemple qu\'il doit y avoir au moins 3 fois le s&nbsp;:
</p>
<code>
"es{3,}t"<br />
</code>
'
);

  
$currentPage->addChapter('classes''Classes de caractères''
<p>
Il est possible de dire qu\'un caractère doit être dans un ensemble donné. Cela se fait à l\'aide des classes de caractères notées entre <strong>crochets [ ]</strong>. On trouve entre ceux-ci la liste des caractères de l\'ensemble. Un exemple permettra de mieux comprendre cela&nbsp;:
</p>
<code>
"ste" =~ "[aeiouy]$"<br />
"est" !~ "[aeiouy]$"<br />
</code>
<p>
Cette expression régulière correspond à une chaîne de caractères qui se terminerait par une voyelle (un des éléments de l\'ensemble a, e, i, o, u, y).
</p>
<p>
Le caractère <strong>.</strong> (point) peut être considéré comme une classe de caractères particulière. Il correspond à n\'importe quel caractère, hormis celui de fin de ligne.
</p>
<code>
"est" =~ "e.t"<br />
"e7t" =~ "e.t"<br />
"et" !~ "e.t"<br />
</code>
<p>
On peut entre les crochets indiquer une suite de caractères consécutifs (selon leur code <acronym xml:lang="en" lang="en" title="American Standard Code for Information Interchange">ASCII</acronym>). Cela se fait grâce au <strong>-</strong> (tiret) qui sépare les deux bornes de l\'intervalle. Par exemple l\'expression régulière suivante&nbsp;:
</p>
<code>
"[b-h]s"
</code>
<p>
Correspondra à toute chaîne contenant une lettre entre b et h suivie par un s. On peut mettre plusieurs suites de caractères et plusieurs caractères seuls entre une seule paire de crochets. Exemples&nbsp;: 
</p>
<code>
ect =~ "e[a-hT-Z04]t"<br />
e4t =~ "e[a-hS-Z04]t"<br />
teSt =~ "e[a-hS-Z04]t"<br />
eit !~ "e[a-hS-Z04]t"<br />
</code>
<p>
La classe de caractères correspond à un caractère entre a et h, entre T et Z, égal à 0 ou égal à 4. Le troisième exemple rappelle qu\'en l\'absence d\'indication de positionnement avec ^ ou $ la chaîne recherchée peut se trouver n\'importe où.
</p>
<p>
On peut inverser le comportement de ces classes en utilisant le caractère <strong>^</strong> juste après le crochet ouvrant. Ce caractère spécial n\'a pas ici le même sens que précédemment donc. S\'il se trouve à l\'intérieur de la définition de la classe de caractères, cela indique que la chaîne doit contenir le caractère ^ tel quel.
</p>
<code>
"est" =~ "e[^a-h]t"<br />
"eft" !~ "e[^a-h]t"<br />
</code>
<p>
Ici, on ne doit pas avoir une lettre entre a et h placée après le e et avant le t (qui eux doivent être présents).
</p>
<p>
Une classe entre crochets peut être suivie d\'un des quantificateurs ou de la notation entre accolades vus précédemment.
</p>
<p>
Pour terminer ce paragraphe, il faut citer les classes pré-définies. Elles sont de la forme&nbsp;: 
</p>
<code>
[:nom_de_la_classe:]
</code>
<p>
Les crochets indiqués ici sont utiles pour définir le nom de la classe elle-même. On aura en plus les crochets entourant l\'utilisation de ces classes prédéfinies.
</p><p>
Voici les classes existantes et les caractères englobés dans ces classes pré-définies&nbsp;: 
</p>
<ul>
<li><strong>alnum</strong>&nbsp;: Un caractère alphanumérique.</li>
<li><strong>alpha</strong>&nbsp;: Un caractère alphabétique.</li>
<li><strong>blank</strong>&nbsp;: Un caractère blanc (espace ou tabulation).</li>
<li><strong>cntrl</strong>&nbsp;: Un caractère de contrôle.</li>
<li><strong>digit</strong>&nbsp;: Un chiffre.</li>
<li><strong>graph</strong>&nbsp;: Un caractère imprimable sauf l\'espace.</li>
<li><strong>lower</strong>&nbsp;: Une lettre minuscule.</li>
<li><strong>print</strong>&nbsp;: Un caractère imprimable y compris l\'espace.</li>
<li><strong>punct</strong>&nbsp;: Un signe de ponctuation (tout caractère imprimable qui ne soit pas alphanumérique ou un espace).</li>
<li><strong>space</strong>&nbsp;: Un caractère d\'espacement (espace, tabulation, saut de ligne ou de page).</li>
<li><strong>upper</strong>&nbsp;: Une lettre majuscule.</li>
<li><strong>xdigit</strong>&nbsp;: Un chiffre hexadécimal (0-9, a-f, A-F).</li>
</ul>
<p>
On peut utiliser ensemble plusieurs de celles-ci et les combiner avec les notations précédentes. Voici quelques exemples&nbsp;:
</p>
<code>
"est" =~ "e[[:alpha:]]t"<br />
"e4t" !~ "e[[:alpha:]]t"<br />
"e4t" =~ "e[[:alpha:][:digit]]t"<br />
"e4t" =~ "e[[:alpha:]0-4]t"<br />
"e8t" !~ "e[[:alpha:]0-4]t"<br />
</code>
<p>
L\'expression régulière du troisième exemple aurait pu être remplacée par "e[[:alnum:]]t".
</p>
'
);

  
$currentPage->addChapter('sub''Sous-expressions''
<p>
On peut délimiter dans une expression régulière une sous-expression. Cela se fait à l\'aide de <strong>parenthèses ( )</strong> l\'entourant. Comme pour les accolades, il est utile de les précéder de \ avec grep.
</p><p>
L\'intérêt est que les sous-expressions ainsi délimitées sont sauvegardées dans des <strong>variables positionnelles</strong> notées <strong>\1</strong>, <strong>\2</strong> et ainsi de suite dans l\'ordre où elles sont définies. On peut ensuite les réutiliser.
</p>
<code>
assa =~ "([[:alpha:]])ss\1"<br />
issi =~ "([[:alpha:]])ss\1"<br />
assi !~ "([[:alpha:]])ss\1"<br />
</code>
<p>
Cette expression régulière recherche une lettre quelconque suivie de deux fois la lettre s. Puis ensuite doit être présente la même lettre que celle rencontrée auparavant.
</p>
'
);

  
$currentPage->display();
?>