Expressions rationnelles

Un article de Haypo.

Retour aux articles de programmation

Les expressions rationnelles, expressions régulières, regexp, ou encore regex, sont une notation permettant de vérifier qu'une chaîne de caractère correspond à un motif donné. On peut s'en servir pour vérifier que des chaînes saisies sont valides, pour extraire des informations, ou encore pour remplacer un motif par une nouvelle expression. Il existe de très nombreux programmes permettant d'utiliser les expressions rationnelles (sed, perl, etc.).

Exemples :

  • « [A-Za-z]+ » reconnaît un mot composé de lettres minuscules ou majuscules (sans lettre accentuée ou c-cédille)
  • « [0-9]{4} » reconnaît un nombre de quatre chiffres exactement
  • « (chien|chat)s? » reconnaît chien, chat, chiens ou chats

Sommaire

[modifier] Syntaxe

  • « [abc] » : Reconnaît un caractère parmi un ensemble donné (ici les lettres a, b et c). On peut spécifier des suites de caractères comme « [a-z] » pour lettre de a à z. Attention, le caractère doit être spécifié en dernier (« [a-z-] » par exemple), et le caractère « ^ » doit être échappé (« [abc\^] »).
  • « [^abc] » : Reconnaît un caractère en dehors de l'ensemble spécifié (ici, tout sauf les lettres a, b et c). On peut également spécifier des suites.
  • « a|b|c » : Ou logique, reconnaît le motif a, b ou c. Il faut souvent utiliser de parenthèses pour bien délimiter les expressions : « Il faut (beau|froid) aujourd'hui ».
  • « ^ » et « $ » : Notent, respectivement, le début et la fin de la chaîne (voir souvent le début et la fin d'une ligne).

On peut ensuite spécifier le nombre de répétition d'une expression :

  • « {n} » : Exactement n
  • « {n,} » : Au moins n
  • « {n,p} » : Entre n et p
  • « ? » : Zéro ou un
  • « * » : Zéro ou plusieurs
  • « + » : Au moins un

[modifier] Syntaxe spécifique à un programme

Expression sed vi grep egrep emacs
Au moins un \+ \+ \+ + +
Zéro ou un \? \? \?  ?  ?
Zéro ou plusieurs * * * * *
Début / fin de ligne ^ $ ^ $ ^ $ ^ $ ^ $
Ensemble [...] [...] [...] [...] [...]
Ou logique a \| b \| c a \| b \| c a \| b\| c a | b | c a \| b \| c
Entre une et trois répétitions \{1,3\} \{1,3\} \{1,3\} {1,3} {1,3}
Capturer une expression \(...\) \(...\) \(...\) (...) \(...\)

[modifier] "Optimiser" ses expressions rationnelles (ou éviter les pièges)

Voir mon projet hachoir-regex qui vise à optimiser les regex et gère bien plus de cas que ce qui est décrit ci-dessous

Certaines expressions peuvent mettre à genoux n'importe quel moteur d'expressions rationnelles. Exemple :

^(x+|y)*$

Cette expression reconnait, par exemple, les chaînes suivantes : "", "x", "y" ou encore "xxyxx". Le problème est le cas "x+*", ce qui peut donner "x+++".

En regardant l'expresion de plus près, on voit qu'en fait le + de x+ est optinnel. Ce qui donne finalement :

^(x|y)*$

De même, l'expression suivante donne le cas "y*+" plutôt confus :

^(x|y*)+$

Il vaut mieux remplacer l'expression par (euh, je ne suis pas certain de mon coup) :

^(x(x|y)*)?$

Mais attention car le contenu des parenthèses n'est pas identique à chaque fois !

[modifier] Liens externes