Jul 03, 2024

Wiki

Python

Aide

edit SideBar

Search

Les Assertions


Le problème

On suppose que l'on souhaite reconnaître un nom de fichier, et le séparer en deux : le nom, et l'extension. L'expression rationnelle qui convient est :

.*[.].*\$

On peut noter les points suivants :

  • le . est ici utilisé comme méta-caractère, signifiant « tout ce qui n'est pas \n », et comme point (pour le reconnaître en tant que tel, on l'a placé entre crochets : [.]).
  • le \$ est présent pour s'assurer que tout le reste de la chaîne fera partie de l'extension.

Supposons maintenant que l'on souhaite relever les noms de fichiers dont l'extension n'est pas .bat...

Une première solution, lourde

L'expression rationnelle

.*[.][^b].*\$

qui refuse toute extension commençant par la lettre b, ne convient pas : foo.bar ne serait pas accepté.

De même, l'expression

.*[.]([^b]..|.[^a].|..[^t])\$

qui demande que l'extension soit :

  • tout sauf un b, suivi de deux caractères quelconques,
  • ou un caractère, suivi de tout sauf un a, suivi d'un caractère quelconque,
  • deux caractères quelconques, suivi de tout sauf un t,

ne convient pas, vu qu'elle suppose que l'expression rationnelle est de taille 3.

Une solution pourrait alors être

.*[.]([^b].?.?|.[^a]?.?|..?[^t]?)\$

c'est-à-dire :

  • On refuse que la première lettre de l'extension soit un b. Il peut y avoir éventuellement une deuxième, voire une troisième lettre.
  • Ou bien, on a une première lettre quelconque, ainsi qu'éventuellement une deuxième lettre, qui ne peut pas être un a, fini par une troisième lettre éventuelle.
  • etc.

Le problème avec cette solution est sa lourdeur. De plus, si le problème change, par exemple si l'on souhaite refuser les extensions .bat et .exe, alors l'expression devient deux fois plus compliquée.

La solution, avec des assertions.

On peut utiliser une assertion négative à la place de tout ce qui précède :

.*[.](?!bat\$).*\$

Il faut comprendre cette assertion de la manière suivante :

  • Si l'expression bat n'est pas reconnue à ce point, continuer à analyser la suite du motif ;
  • Si bat\$ est reconnu, alors l'ensemble de la reconnaissance échoue : la chaîne ne satisfait pas l'expression rationnelle.

Le dollar \$ est nécessaire, vu que fichier.batch doit être accepté : le problème se situe quand, derrière bat, il n'y a plus rien.

On peut alors, avec ces assertions négatives, refuser facilement une autre extension :

.*[.](?!bat\$|exe\$).*\$

Les assertions

Il existe deux types d'assertions : positive et négative.

(?=exp)
Assertion positive.
Réussit si et seulement si l'expression rationnelle exp est reconnue à l'endroit où l'analyse se situe actuellement.
  • Si la reconnaissance échoue, alors l'expression rationnelle n'est pas reconnue.
  • Si la reconnaissance marche, alors l'analyse se poursuit (le moteur de reconnaissance n'avance pas dans la chaîne).
(?!...)
Le contraire de ce qui précède.

Page Actions

Recent Changes

Group & Page

Back Links