begin process at 2008 07 05 06:12:18
1 205 051 membres
37 nouveaux aujourd'hui
14 118 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

MATCHESMASK ET LES EXPRESSIONS RÉGULIÈRES.


Information sur la source



Description

A part MaskEdit, on ne peut pas dire que Delphi nous offre beaucoup d'outils pour s'initier aux expressions régulières.
Il existe cependant une fonction méconnue, MatchesMask, qui permet de faire des choses intéressantes.
Voici un petit exemple d'utilisation de cette fonction. Cet exemple permet d'extraire des adresses IP ou des N° de téléphone à partir d'un texte quelconque.
MatchesMask nous permet de faire une recherche dans un String par dichotomie. Méthode beaucoup plus rapide qu'une recherche classique qui balaie toute la String.
MatchesMask a cependant un inconvénient. C'est qu'elle n'offre pas toute la souplesse proposée par les expressions régulières des autres langages. Par contre, elle a un avantage:  c'est que le masque est très simple à mettre en oeuvre et permet ainsi un début d'initiation facile aux regexp...
Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

  • signaler à un administrateur
    Commentaire de florenth le 02/08/2007 18:57:22

    Mes premières impressions: un code 100% fonctionnel qui remplit très bien son rôle tout en restant "simple" et concis.
    Du Cari à l'état pur, quoi !
    Cette fonction MatchesMask() (sûrement la moins bien documentée de l'aide de Delphi) permet donc bien de faire des prouesses.

    A noter quelques détails:
    - J'ai eu besoin de désactiver le "range checking" pour pouvoir exécuter ChercherIP() car la ligne "while MatchesMask(S[M]+S[M+1],'[0-9.][0-9.]') and (M<Length(S)) do inc(M);" lit en dehors de la chaîne (pas bien ! ^^). Par ailleurs, j'en profite pour dire que cette directive devrait toujours être active, ça évite bien des dégâts.

    - C'est quoi cette ligne "Str(GetTickCount-Deb,S);" ??? On utilise IntToStr() à la place ! Et puis comme ça, tu évites ta variable "S". Enfin, c'est pas le plus important.

    - Pour avoir toujours plus de performances, tu peux utiliser un objet TMask (toujours dans Masks.pas) qui te permet d'interpréter la chaîne de masque une seule fois dans toute la fonction. Ainsi, tu vas beaucoup plus vite.

    - Pour certains traitements, les expressions régulières restent incontournables, mais ça, tu l'as déjà dit toi même. Par contre, ce ne sont pas "les expressions régulières des autres langages" comme tu le dis car il existe des librairies qui permettent d'utiliser les regex (compatible prce en plus) depuis Delphi.

    A+
    Flo

  • signaler à un administrateur
    Commentaire de Caribensila le 02/08/2007 19:40:09

    Merci pour tes remarques toujours aussi pertinentes, Florent  :)

    - Tu as raison, ça lit bêtement en-dehors de la chaîne. Le pire c'est que je m'en étais aperçu et que j'avais corrigé. Mais j'ai dû oublier de sauvegarder le changement ( quel con ce Cari! ).

    - "Str(GetTickCount-Deb,S);" c'est juste pour éviter d'utilsiser l'unité 'SysUtils'. Ca m'énerve de rajouter une unité rien que pour une fonction ;)

    - Je vais étudier TMask. Merci pour ce conseil.

    - Je voulais parler des langages comme Perl où les expressions régulières font partie intégrante du langage; c'est plus simple à manipuler. Mais après vérification, tu as raison. Il semble bien que ce soit le seul langage offrant cette facilité.

  • signaler à un administrateur
    Commentaire de Delphiprog le 05/08/2007 22:59:51 administrateur CS

    Que de code pour valider une adresse IP !
    De plus, si je n'ai pas lu trop vite le code, une adresse telle que 00.00.00.00 serait valide ?
    Quant à valider une adresse IP V6, on en est loin.
    Non, sérieusement, la fonction MatchesMask bien que très utile, atteint ses limites dans le cas présent.
    Autant se tourner vers une bonne bibliothèque pour Delphi telle que Regexp Studio (libre et gratuite, pourquoi s'en priver ? http://www.regexpstudio.com/).

    Florenth : c'est PCRE (Perl Compatible Regular Expressions) et non prce (voir http://en.wikipedia.org/wiki/PCRE)

    Désolé d'avoir un peu cassé l'ambiance mais il m'a semblé nécessaire de remettre les choses dans leur contexte.
    D'un côté on a une chaine à analyser et de l'autre, une expression régulière. Le moteur se charge alors de vérifier que le pattern est applicable à la chaine et d'en extraire une partie ou toutes les parties.
    Dans le code de Caribensila, c'est une fonction dédiée à la vérification qui est codée. C'est peut-être plus performant pour cet usage, mais c'est moins souple et moins réutilisable sur le long terme.
    D'où l'intérêt d'apprendre les expressions régulières même si ça parait rebutant au premier abord. Quand on les a manipulé un certain nombre de fois et qu'on pratique plusieurs langages, le savoir devient immédiatement réutilisable et ça, ça n'a pas de prix.

    Allez, quelques bonnes pistes :
    Quick reference : l'essentiel des regexp en une page
    http://www.night-ray.com/regex.pdf
    Pour le reste : http://tinyurl.com/2jwkgd

    Bon, c'est encore les vacances pour certains. Si vous cherchez de la lecture intéressante, y a qu'à demander.

  • signaler à un administrateur
    Commentaire de florenth le 06/08/2007 13:22:50

    Je trouve ta critique envers ce code un peu dure.
    Si le but de cette source est de montrer l'utilité de la fonction MatchesMask() et ses domaines d'application, alors ce but est parfaitement rempli, même si les IPs validées ne sont pas toutes justes (c'est juste une question de pertinence).

    Cela dit, je suis d'accord avec toi sur l'utilité des expressions régulières et ce n'est pas pour rien que je les utilise couramment.
    Excuse aussi mon doigt d'avoir glissé pour écrire le PCRE et mon cerveau pour n'avoir pas détecté la faute.

    D'ailleurs, au passage, pour valider une IP avec une regex, il faut avoir le coeur bien accroché, surtout pour relire ... et pour comprendre !

    CIPRegex = '^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$';

  • signaler à un administrateur
    Commentaire de Caribensila le 06/08/2007 15:39:22

    @Delphiprog

    Tu casses pas l'ambiance, t'en mets!  lol
    Et on a l'habitude et surtout le plaisir de se faire appeler 'Arthur' quand notre cher Delphiprog remet les pendules à l'heure car ce n'est jamais inutile.

    D'autant que ce sont tes quelques réponses sur le forum au sujet des expressions régulières qui m'ont donné l'envie de les connaître et l'idée de les présenter aux autres débutants comme moi (y'a pas que des surdoués, ici). Mais je ne voulais pas les rebuter avec une bibliothèque dédiée et tout l'investissement en temps que ça demande. MatchesMask, dans sa simplicité était une bonne introduction j'ai pensé (voir l'exemple gerbant de Florenth avec regex).

    De plus, comme le souligne Florenth, ce n'est pas un code d'extraction d'IP que j'ai posté. Tout au plus un code d'extraction de 'trucs qui ressemblent à des IP' (Comment savoir si 123.125.365.325 est une IP valide ou un N° de tél de Papouasie?). Ce n'était qu'un prétexte pour illustrer MatchesMask qui est peu connue. Et si on arrive aux limites de cette fonction, ça aura au moins servi à montrer MatchesMask() et ces limites.

    Quant à valider une IPv6, j'y suis arrivé très facilement avec quelques changements triviaux dans les masques et la gestion des doubles-points qui se suivent. Et si j'y arrive, c'est que c'est pas difficile.  ;)

    On est donc d'accord sur l'intérêt d'étudier les expressions régulières. Mais sans effrayer, en douceur.  :)))
    Ensuite..?  Il y a les bonnes pistes que tu as signalées. Merci à toi et à Flo.

  • signaler à un administrateur
    Commentaire de florenth le 06/08/2007 18:17:13

    Au fait Cari, pourquoi MatchesMask pour trouver une IP ?
    Je n'y avais pas pensé avant, mais c'est super simple :




    Matériel: un TEdit, un TButton et un TMemo
    --------------------------------------------------------------------
    function ParseString(const S: string; var Position: Integer;
      AllowedChars: TSysCharSet): string;
    var
      Debut: Integer;
    begin
      Debut := Position;
      while (Position <= Length(S)) and (S[Position] in AllowedChars) do
        Inc(Position);
      Result := Copy(S, Debut, Position - Debut);
    end;

    type
      TIPAddr = array[0..3] of Byte;

    function IsValidIP(const S: string; out IPAddr: TIPAddr): Boolean;
    var
      Num, Position, TempI: Integer;
    begin
      Result := False;
      Position := 1;
      for Num := 0 to 3 do
      begin
        TempI := StrToIntDef(ParseString(S, Position, ['0'..'9']), -1);
        if not (TempI in [0..255]) then
          Exit;
        IpAddr[Num] := TempI;
        if (Num <> 3) and (S[Position] <> '.') then
          Exit;
        Inc(Position);
      end;
      Result :=  Position > Length(S);
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    var
      IP: TIPAddr;
      I: Integer;
    begin
      if IsValidIP(Edit1.Text, IP) then
      begin
        Memo1.Clear;
        Memo1.Lines.Add('IP Valide');
        for I := 0 to 3 do
          Memo1.Lines.Add(IntToStr(IP[I]));
      end
      else
        Memo1.Text := 'IP non valide';
    end;
    --------------------------------------------------------------------

    Alors, qu'en penses-tu ?

    Et puis dis moi, tu vas pas t'arrêter là maintenant que tu t'y est lancé ! Pour la semaine prochaine, un petit exemple avec une regex, ça te tente pas ?? ;-)

    PS: mon exemple n'est pas "gerbant", c'est juste que à part celui qui l'a écrit (donc moi), les autres vont mettre du temps à comprendre le pourquoi du comment.
    Quoi que à ce qu'il parait, on peut mettre des commentaires dans les regex...

  • signaler à un administrateur
    Commentaire de Delphiprog le 07/08/2007 09:24:55 administrateur CS

    Mille excuses à vous deux mais je n'avais pas l'intention de froisser les esprits. Je sais fort bien que Caribensila n'est pas du genre à poster des codes à deux balles. Qu'il me pardonne s'il s'est senti offensé et je lui ferai parvenir une tarte au concombre pour me faire pardonner. :o)
    Le message que j'ai voulu faire passer est l'intérêt, sur le long terme, de se pencher sur l'étude des expressions régulières du fait qu'elle sont disponibles dans quasiment tous les langages et presque universelles (différentes normes existent).
    Le temps passé à écrire la fonction postée ici aurait été bien moindre avec les expressions régulières.
    Le fait d'utiliser telle ou telle bibliothèque importe peu du moment que la bibliothèque en question respecte les normes "industrielles".

    @florenth : pour info, voici l'expression que j'utilise pour valider une adresse IP V4 :
    ^(([01]?\d\d?|2[0-4]\d|25[0-5])\.){3}[01]?\d\d?|2[0-4]\d|25[0-5]$

    Ceci démontre, par la même occasion, qu'il n'y a pas qu'une vérité et qu'on peut parvenir au résultat recherché de différentes manières.
    Désolé, mais je n'ai pas mis de commentaire dans cette expression régulière.
    Pour finir, je suis entièrement d'accord avec vous deux pour dire que la fonction MatchesMask est très largement méconnue et donc, à fortiori, sous utilisée. C'est bien dommage et merci à Caribensila de l'avoir remise au goût du jour.

  • signaler à un administrateur
    Commentaire de Renfield le 07/08/2007 09:33:42 administrateur CS



    ta regexp ne me convient pas tout a fait. Elle décrit :

    255
    comme étant une IP valide...

    de plus, si je testes:
    192.168.1.204

    le '4' n'est pas dans le match

    http://www.vbfrance.com/codes/REGEXP-WORKSHOP_17331.aspx

  • signaler à un administrateur
    Commentaire de florenth le 07/08/2007 14:17:47

    @Delphiprog: Il ne s'agit pas de *froissage* d'esprit, ou de tout autre artefact mais plus d'un débat quand à la meilleure méthode pour effectuer ce genre de recherche.
    Dans ce contexte, ta remarque est tout à fait la bienvenue. En plus, les liens que tu cites sont à la fois intéressants et complets.

    @Renfield: ton programme a l'air drôlement utile. Seul ennui: c'est du VB ! Comment on fait pour s'en servir ? Tu fournis l'exe mais il manque toujours les ocx pour que ça veuille bien démarrer.

    Sinon, toujours pour rester dans le domaine des regexp, on a toujours le même problème : si j'ai ^(expression1|expression2)$, comment je sais laquelle des deux sous-expressions à été matchée ?

  • signaler à un administrateur
    Commentaire de Renfield le 07/08/2007 18:09:20 administrateur CS

    mon prog doit exister en delphi, .net, etc.

    ce genre de choses :
    ((expr1)|(expr2)

Ajouter un commentaire

Pub



Appels d'offres

CalendriCode

Juillet 2008
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Téléchargements

Logiciels à télécharger sur le même thème :

Boutique

Boutique de goodies CodeS-SourceS