Forum Programmation.perl Liste de conditions

Posté par  (site web personnel) .
Étiquettes : aucune
0
6
juin
2007
Bonjour,

Si je veux vérifier qu'une chaîne matche plusieurs regex, j'aurais tendance à faire naïvement :

if ($s =~ /toto/ && $s =~ /titi/ && ... )


Bon, trouvant ça assez laid, je ferais plutôt

foreach my $qw qw\toto tata titi\{
warn "la chaine ne matche pas $qw" and last unless ($s =~ /$qw/ );
}


L'interet principal étant que j'ai une vrai liste de conditions.

Le problème est que ça marche bien si je veux savoir si ma chaîne ne remplie pas cette liste de conditions . Or je veux savoir si elle la remplie.

Comment, sans passer par une fonction, ni par une variable booléenne vilaine (ça serait trop facile) coderiez-vous cela ?
  • # obfuscating contest!

    Posté par  (site web personnel) . Évalué à 2.

    print !grep (/0/, map { $s =~ /$_/?1:0} qw/toto tata titi/ ) ? "OK" : "NOK";

    explication:
    map {} qw// : remplace le tableau de conditions par un tableau de 1 ou 0 suivant si la condition est verifiee.

    Ce tableau de 0 et 1 est passe a grep, qui rend le nombre d'occurence de 0.
    si ce nombres d'occurence est non nul, tout est verifie, sinon erreur.

    De la a dire que c'est plus clair que le foreach, il y a un pas que je ne franchirai pas.
    • [^] # Re: obfuscating contest!

      Posté par  (site web personnel) . Évalué à 2.

      peut etre est-ce un peu plus elegant (quoiqu'en fait non):

      map { return 0 unless($s =~ /$_/) } qw/toto tata titi/;
      return 1;

      mais tout ca n'est qu'une astuce pour simuler une variable booleenne vilaine.
      • [^] # Re: obfuscating contest!

        Posté par  (site web personnel) . Évalué à 1.

        eval '$s=~/' . join ('/ && $s=~/', qw /toto tata titi/) . '/';

        comme ca tu as tout de meme toutes tes conditions dans un seul tableau.

        Ou si elle sont simples:

        eval '$s=~/[' . join ('|', qw/toto tata titi/) . ']/';
        • [^] # Re: obfuscating contest!

          Posté par  (site web personnel) . Évalué à 2.

          Merci pour vos réponses imaginatives ;-). Elles me permettent de voire qu'il n'y a aucune solution "naturelle" qui m'aurait échappé.

          Pour des raisons de lisibilité, je passerai évidemment par une sub. En gardant mon foreach


          sub est_ce_bien_vrai($@) {
          my ($s, @qw) = @_;
          foreach (@qw) {return 0 unless ($s =~ /$_/ );}
          return 1;
          }



          .
          • [^] # Re: obfuscating contest!

            Posté par  . Évalué à 1.

            Un peu en retard.... :)

            Tu peux aussi regarder du coté de Regexp::List, Regexp::Assemble et autres...

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.