Introduction aux expressions régulières

Les expressions régulières (ou regex) permettent de vérifier qu’une chaine est conforme à un masque (ou pattern).
Cet outil permet des reconnaissances ou substitutions complexes. Les regex sont implémentées dans la plupart des langages de programmation : sachant cela, lorsque vous apprendrez un nouveau langage, vous n’aurez pas à ré-apprendre complètement vos notions sur les expressions régulières, même si quelques légères différences peuvent survenir.

Les expressions régulières (ou regex) permettent de vérifier qu’une chaine est conforme à un masque (ou pattern).

Cet outil permet des reconnaissances ou substitutions complexes.
Les regex sont implémentées dans la plupart des langages de programmation :
sachant cela, lorsque vous apprendrez un nouveau langage, vous n’aurez pas à ré-apprendre
complètement vos notions sur les expressions régulières, même si quelques légères différences peuvent survenir.

Les patterns sont constitués de caractères “normaux” et de métacaractères.

Un métacaractère est un caractère ayant une signification particulière (des signes de ponctuation en général).

Il n’est pas mis dans le masque “pour lui même”.

Les lettres et chiffres ne sont pas des métacaractères : ils sont mis pour eux mêmes : lorsqu’un masque contient “A”, le moteur de regex cherchera bien un A majuscule dans la chaine testée.

{n,} : “n fois ou plus”

ex : /AB{3,}C/ reconnait A suivi de 3 B ou plus, puis un C.

{n,m} : “entre n et m fois”

ex : /AB{3,5}C/ reconnait A suivi de 3 à 5 B puis C.

Remarque : ?,*,+ peuvent être exprimés par un équivalent entre accollades.

METACARACTERES DE POSITION

^ : “Début de chaine” (si positionné en début de masque)

Comme vous l’aurez remarqué, par défaut une recherche de regex regarde si la chaine testée CONTIENT une sous chaine vérifiant le masque.

^ permet de changer ca : /^ABC/ reconnaitra une chaine qui COMMENCE par ABC : “ABCDE” est reconnu, pas “AZABCDE”

$ : “Fin de chaine” (si positionné en fin de chaine)

/^ABC$/ permet donc de reconnaitre une chaine qui est EXACTEMENT “ABC” ;-)

METACARACTERES DE GROUPEMENT

Les parenthèses servent à regrouper plusieurs “briques” de regex.

Ex : on souhaite reconnaitre “ab” un nombre indéfini de fois, suivi d’un “c”.

On utilisera le masque : /(ab)*c/

Les parenthèses servent également pour l’alternative : le ”|” signifie “OU”.
ex : on veut reconnaitre : “ab” ou “bc” suivi d’un “d”
Le pattern sera : /(ab|bc)d/

Les parenthèses ont une troisième fonction, la capture, que je ne développerai pas ici : grosso modo, tout ce qui est entre des parenthèses peut être réutilisé plus loin dans la regex (backref), ou dans un remplacement, ou simplement retrouvé après un “if” par exemple.

METACARACTERES DE CLASSE

Une classe est un ensemble de caractères, elle est définie entre crochets.
ex : un ensemble contentant a,b,e,g, et z : [abegz]

A la différence des parenthèses, une classe ne reconnaitra qu’un seul caractère au maximum.
Seconde différence, une classe peut être “complémentée”, en la commencant par un ^ :
ex : reconnaitre “tout caractère différent d’un z” : [^z]

Utile dans les classes, la réunion : le tiret ”-” permet de raccourcir des classes qu’on utilise fréquemment.
Pour reconnaitre une lettre minuscule, on utiliserait a priori :
[abcdefghijklmnopqrstuvwxyz]
C’est lourd, on préfèrera la notation : [a-z]
Marchent également : [A-Z], [0-9], [a-zA-Z] (contient toutes les lettres), [a-ft-z], etc..

Le tiret est donc un métacaractère lorsqu’il est utilisé dans une classe. _ Pour mettre un tiret dans une classe, on le mettra simplement sur le bord : [a-z-] contient les lettres de a à z ainsi qu’un tiret.

/ !\ Méditez ceci :
if (preg_match("/[^a-z]/",$string)) ...
Cette condition vérifie que $string contient un caractère qui n’est pas une lettre minuscule.
Cette condition NE DIT PAS : vérifie que $string ne contient pas de lettre minuscule.

METACARACTERE \

Il a 3 fonctions :

1- échappement
Un + signifie “1 fois ou plus”, d’accord, mais comment reconnaitre un plus “+” ? Il suffit de mettre \+ (de la même facon qu’on échappe les guillemets dans des chaines php ou perl)
Le backslash est donc lui même un métacaractère.
Voici une liste des métacaractères qu’on peut ainsi échapper : ^ $ * + ? . | ( ) [ ] \
Il permet aussi d’échapper le caractère utilisé comme délimiteur histoire d’éviter les confusions : j’ai utilisé des slashes, on peut utiliser d’autres chars : voici les courants : ==, #masque#, /masque/.

2- devant des lettres, pour une signification particulière
<strong>\s</strong> : un espace blanc, \t, \r, \n, \f
<strong>\S</strong> : pas un espace
<strong>\d</strong> : un chiffre (équivalent à [0-9])
<strong>\D</strong> : pas un chiffre
<strong>\w</strong> : un mot (équivalent à [a-zA-Z_])
<strong>\W</strong> : pas un mot
Moultes autres selon les langages, ceux ci sont les plus utilisés.

3- références arrière
Point très intéressant, non traité ici car trop compliqué pour une première approche.

LIENS UTILES

perldoc.perl.org/perlre.html : la doc de référence des regex en Perl (qui implémente les regex au coeur du langage)
www.pcre.org : le site officiel de la lib pcre (qui équipe pas mal de langages)
www.expreg.com : site francais très bien fait sur les regexp
www.scriptsdb.org/tutar.php ?id=1 : tuto sur les regex en mIRC (celui par lequel j’ai commencé)

SUJETS LAISSES A UNE PROPA ULTERIEURE

opérateurs non gourmands
- utilisation des backref et des captures
- assertions positives et négatives
- optimisations de regex, conditions
- support unicode (valide en php ? php 5.1 ?)
- métacaractères non cités
- interpolations de variables, échappements
- classes POSIX
- vue des modificateurs et modes de reconnaissance
- équivalence de fonctions php ou Perl standard (voir http://www.expreg.com/equivalence.php)
- UrlRewriting
- ...

CONCLUSION

Attention cependant : le travers naturel quand on commence à bien maitriser cet outil, c’est de faire pas mal de choses avec qu’on aurait fait sans sinon.
Ce qui peut devenir ennuyeux pour des problèmes d’optimisation ;-)
Durant votre progession, l’important est de faire des tests, d’apprendre par la pratique et l’observation : les moteurs de regex ont un fonctionnement complexe : au delà d’un certain niveau, on peut trouver des “bugs” donc testez vos masques !