lalahop

Les expressions régulieres

Ceux qui me connaissent savent que je suis assez fan des expressions régulières depuis que je les ai connues.

Je me souviens encore de quelques unes des regex que j'ai écrit, il y a entre 3 et 5 ans et pour cause : elles trainent toujours dans un coin de mon disque dur. Toutes n'étaient pas optimisées, loin s'en faut. Mais, comme on l'entend fréquemment, l'expérience est le nom que nous donnons à nos erreurs 🙂 .

J'ai découverts les regex en PHP et à l'époque ça donnait ça :

*Retour dans le passé*

Pour récupérer la version d'Apache dans un phpinfo() :
#Apache/(.+) \(Fedora\)#

Pour récupérer la version de PHP dans un phpinfo() :
#PHP Version (.+)</h1>#

Pour contrôler un nom de fichier passé en GET afin d'éviter la remontée de répertoires :
'`\.`'

Pour récupérer plusieurs liens sur un site donné (j'ai oublié lequel :/) :
#<p><font face=\"Arial\"><a href="(.+)">(.+)</a>(.+) (.+)</font></p>#isU

La même mais pour des adresses email :
#<A HREF="mailto:(.+)">.+</A>#isU

Et on parle même pas de celles liées au BBCode :
#\[b:[a-z0-9]{8}\](.+)\[/b:[a-z0-9]{8}\]#isU
#\[i:[a-z0-9]{8}\](.+)\[/i:[a-z0-9]{8}\]#isU
#\[u:[a-z0-9]{8}\](.+)\[/u:[a-z0-9]{8}\]#
#\[color=(.+):[a-z0-9]{8}\](.+)\[/color:[a-z0-9]{8}\]#isU

#\[size=(.+):[a-z0-9]{8}\](.+)\[/size:[a-z0-9]{8}\]#isU
#\[quote:[a-z0-9]{8}\](.+)\[/quote:[a-z0-9]{8}\]#isU
#\[quote="(.+)":[a-z0-9]{8}\](.+)\[/quote:[a-z0-9]{8}\]#isU
#\[code:[a-z0-9]{8}\](.+)\[/code:[a-z0-9]{8}\]#isU
#\[list:[a-z0-9]{8}\]#isU
#\[list=[0-9]:[a-z0-9]{8}\]#isU
#\[/list:u:[a-z0-9]{8}\]#isU
#\[/list:o:[a-z0-9]{8}\]#isU

#\[\*:[a-z0-9]{8}\](.+)\[/\*:[a-z0-9]{1}:[a-z0-9]{8}\]#
#(<ul>|<ol>)<br />#
#</li><br />#
#\[img:[a-z0-9]{8}\](.+)\[/img:[a-z0-9]{8}\]#isU

#\[url:[a-z0-9]{8}\](.+)//(.+)\[/url:[a-z0-9]{8}\]#isU
#\[url=(.+)//(.+):[a-z0-9]{8}\](.+)\[/url:[a-z0-9]{8}\]#isU

*Retour dans le présent*

Récemment, j'ai eu à vérifier la validité d'un NIR pour un cas d'école et j'ai de suite pensé aux regex.

Voila les regex que j'ai écrit. Comme pour les autres regex présentées dans cet article, je n'en garantit pas la validité. J'ai testé tous les cas possibles mais une erreur peut toujours arriver (un code sans bugs est un code insuffisamment testé). On peut également les optimiser, ne serai-ce qu'en utilisant les classes de caractères. Ce coup-là, c'est Java qui sera utilisé :

Pour vérifier la validité de la clé :

^[0][1-9]|[1-8][0-9]|9[0-7]$

Pour le reste du NIR :

^[12][0-9][0-9](?:0[1-9]|1[012]|20)(?:(?:2[aA]|2[bB]|[0-8][1-9]|9[0-5])(?:[0-9][0-8][1-9]|[1-9][1-8][0-9]|990)|(?:(?:9[78][0-9](?:0[1-9]|[1-8][0-9]|90)))|99(?:[0-9][0-8][1-9]|[1-9][1-8][0-9]|990))(?:[0-9][0-9][1-9]|[1-9][1-9][0-9])$

L'avantage des regex, c'est qu'on trouve toujours quelqu'un qui en a un jour écrit une plus longue que la nôtre. Mais je pense que la reine des regex, c'est celle qui contrôle la validité d'une adresse email, et pour cause : la RFC 5322 (qui remplace la 2822 qui elle-même remplace la 822) qui définit le format des adresses email est à la fois diabolique et sadique. Quelques liens pour se faire une idée : Mail::RFC822::Address: regexp-based address validation et How to Find or Validate an Email Address.