IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Problème d'expressions régulières


Sujet :

Langage Perl

  1. #1
    Membre du Club
    Profil pro
    DBA Oracle / MySQL / SQLServer
    Inscrit en
    Janvier 2005
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : DBA Oracle / MySQL / SQLServer

    Informations forums :
    Inscription : Janvier 2005
    Messages : 95
    Points : 54
    Points
    54
    Par défaut Problème d'expressions régulières
    Bonjour,

    Je suis en train d'essayer de faire un script perl qui parcourt des fichiers et des dossiers et y applique des expressions régulières afin de faire du renommage en masse.

    Mon pb : si je passe mon expression régulière en paramètre de mon script ce la ne fonctionne plus, pourtant si je l'affiche avec la fonction print pour la voir elle est bonne.

    $newfile =~ s/\s/_/g;
    -> fonctionne

    $newfile =~ $expr;
    echo $expr;
    -> affiche s/\s/_/g MAIS ne fonctionne pas.

    Si quelqu'un peut m'expliquer d'ou vient le problème, d'avance merci.

  2. #2
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Une regex n'est pas une simple chaîne de caractère, il y a de la syntaxe à l'intérieur... Est-ce qu'il te viendrait à l'idée d'écrire un code comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    if( $ARGV[0] ){
        print "$ARGV[0] est vrai !\n";
    }
    puis de t'attendre à ce qu'il estime que "5 > 6" est faux ?
    C'est le même phénomène.

    Ici comme tu mets =~ perl s'attend à trouver une regex, il trouve une chaîne de caractère, il assume donc que la chaîne de caractère est la regex à matcher, autrement dit, dans ton exemple il essaie de faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $newfile =~ m{s/\s/_/g};
    Pas tout à fait ce que tu voulais, n'est-ce pas ?

    Pour obtenir ce que tu veux, il faut soit que tu utilises un eval "" (solution complètement non sécurisée que je ne te recommande pas : tu peux mettre n'importe quoi en paramètre, pas seulement une regex...), soit que tu passes les deux partie de la regex isolément avant de les réutiliser proprement dans ton code (ce qui est complètement non sécurisé également si tu ne fais pas d'autre contrôle sur le contenu de la regex, mais qui est déjà plus propre) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $newfile =~ s/$ARGV[0]/$ARGV[1]/ge;
    (NB : tu ne peux pas passer le flag g ou e ainsi, mais je pense que ça devrait plutôt être controlé par une option si tu veux proposer le choix de toute façon, les autres flags sont utilisable via la syntaxe des regexs)

    --
    Jedaï

  3. #3
    Membre du Club
    Profil pro
    DBA Oracle / MySQL / SQLServer
    Inscrit en
    Janvier 2005
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : DBA Oracle / MySQL / SQLServer

    Informations forums :
    Inscription : Janvier 2005
    Messages : 95
    Points : 54
    Points
    54
    Par défaut
    Merci pour ta réponse clair et précise !

    $newfile =~ s/$ARGV[0]/$ARGV[1]/ge;
    En fait je faisais ça avant mais par exemple si j'utilise \s pour $ARGV[1] ça ne met pas d'espace mais un \s !!
    De plus je n'arrive pas à appliquer s/[0-9][0-9]\s/\1\2_/g
    avec s/$ARGV[0]/$ARGV[1]/ge, \1 et \2 ne sont pas interprétés ..

    (NB : tu ne peux pas passer le flag g ou e ainsi
    oui mais pourquoi, c'est la meme chose que pour $ARGV[0] ?

    En ce qui concerne eval, comment doit etre la syntaxe ??

    $newfile =~ eval"$expr";
    Merci

  4. #4
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par Franckinux
    En fait je faisais ça avant mais par exemple si j'utilise \s pour $ARGV[1] ça ne met pas d'espace mais un \s !!
    De plus je n'arrive pas à appliquer s/[0-9][0-9]\s/\1\2_/g
    avec s/$ARGV[0]/$ARGV[1]/ge, \1 et \2 ne sont pas interprétés ..
    Normal, d'une part il n'y a pas de groupe capturant dans la première partie de la regex, d'autre part dans la seconde partie on n'utilise plus \1 ou \2, on utilise $1 ou $2 (il y a tout de même un petit problème dans mon exemple, bien que je ne sois pas sûr du pourquoi...). Les \s marchent parfaitement dans la première partie (ils ne sont pas censés marcher dans la seconde partie !! Après tout ils matchent plusieurs caractères, alors lequel sont-ils censés imprimer), j'ai testé. Petite correction pour faire marcher les $n dans la seconde partie (quelqu'un voit pourquoi ça ne marchait pas ?) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     $newfile =~ s/$ARGV[0]/qq(qq($ARGV[1]))/gee;
    --
    Jedaï

  5. #5
    Membre du Club
    Profil pro
    DBA Oracle / MySQL / SQLServer
    Inscrit en
    Janvier 2005
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : DBA Oracle / MySQL / SQLServer

    Informations forums :
    Inscription : Janvier 2005
    Messages : 95
    Points : 54
    Points
    54
    Par défaut
    merci pour ta réponse, mais je ne comprend pas le

    qq(qq($ARGV[1]))
    et donc pour \s sur la deuxième chaine, je ne peux pas remplacer par des espaces alors ?

  6. #6
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    \s est un séquence de caractère spéciale qui n'a de sens que dans une expression régulière (et la deuxième partie d'une substitution n'est pas une regex, elle est traitée comme une chaîne de caractère normale, où \s n'a pas de sens), pourquoi voudrais-tu mettre \s en seconde partie ?
    Si tu veux mettre un espace dans la seconde partie tu peux tout à fait, évidemment.

    Il doit y avoir une façon plus élégante de faire, mais je n'ai pas trouvé (pas trop cherché non plus). Ce bricolage permet d'employer les variables $1, $2, etc. dans la seconde partie si on le souhaite (couplé avec les deux /e).
    (j'ai compris pourquoi ma précédente tentative ne marchait pas d'ailleurs, en tout cas celle-ci marche).

    --
    Jedaï

  7. #7
    Membre du Club
    Profil pro
    DBA Oracle / MySQL / SQLServer
    Inscrit en
    Janvier 2005
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : DBA Oracle / MySQL / SQLServer

    Informations forums :
    Inscription : Janvier 2005
    Messages : 95
    Points : 54
    Points
    54
    Par défaut
    oui effectivement pour l'espace il n'a rien à matcher et ça marche avec un vrai espace !!

    pour la regexpr pour utiliser les variables dans la seconde chaine, j'ai quand meme vraiment du mal :

    je lance sur un fichier 04 monfichier:

    s/[0-9][0-9]\s/qq(qq(_))/gee
    et j'obtiens comme nom de fichier :

    qq(qq(_))monfichier

    j'ai du raté un truc énorme ?!!

  8. #8
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    perl -e "$s = qq(04 monfichier); $s =~ s/[0-9][0-9]\s/qq(qq(_))/gee; print $s"
    Ceci marche parfaitement, montre nous ce que tu fais vraiment puisqu'à priori tu fais une erreur quelque part... (avec le code que je t'ai donné, le second paramètre du script doît être "_" et pas "qq(qq(_))" hein, c'est le code qui se charge de tout faire comme il faut après.)

    --
    Jedaï

  9. #9
    Membre du Club
    Profil pro
    DBA Oracle / MySQL / SQLServer
    Inscrit en
    Janvier 2005
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : DBA Oracle / MySQL / SQLServer

    Informations forums :
    Inscription : Janvier 2005
    Messages : 95
    Points : 54
    Points
    54
    Par défaut
    eh bien je mettais

    $s =~ s/[0-9][0-9]\s/qq(qq(_))/gee
    donc c'est

    $s =~ s/[0-9][0-9]\s/_/gee

  10. #10
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Je ne suis pas sûr que tu ais bien compris : quand je parle de paramètres d'un script, je parles de paramètre en ligne de commande. Je te redonne donc un exemple de la méthode que j'utiliserai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    perl -e "$s = q(04 monfichier); $s =~ s/$ARGV[0]/qq(qq($ARGV[1]))/gee; print $s"  "[0-9][0-9]\s"   "_"
    retourne bien :
    _monfichier

    Il est important que tu comprennes ce que tu écris, or visiblement tu ne sais pas à quoi sert le modificateur /e. /e dans une substitution (s///e) a pour effet que la partie gauche est remplacée par le résultat de l'évaluation de la partie droite, pas directement par la partie droite, l'exemple typique de cela est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    my $add = "4+    5";
    $add =~ s/(\d+)\s*\+\s*(\d+)/$1 + $2/ge;
    print $add; # "9", et pas "4 + 5"
    Le modificateur /e est l'un des rares modificateurs dont la quantité ait une importance : pour chaque /e, on évalue la partie droite une fois, donc avec /ee on l'évalue deux fois :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    sub r4 { return 42 }
    sub r5 { return 0 }
    my $add = "4+    5";
    $add =~ s/(\d+)\s*\+\s*(\d+)/"r$1()"."+"."r$2()"/gee;
    print $add; # "42", et pas "r4()+r5()"
    --
    Jedaï

  11. #11
    Membre du Club
    Profil pro
    DBA Oracle / MySQL / SQLServer
    Inscrit en
    Janvier 2005
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : DBA Oracle / MySQL / SQLServer

    Informations forums :
    Inscription : Janvier 2005
    Messages : 95
    Points : 54
    Points
    54
    Par défaut
    oui d'accord j'ai compris tes exemples

    j'ai vraiment du mal, désolé, donc

    s/^([0-9][0-9])\s/$1_/g va donner $1_
    et

    s/^([0-9][0-9])\s/$1_/ge va donner 01_
    n'empèche que si je l'écris en dur dans mon code (puisque je ne peux pas passer la seconde partie en paramètre) ça ne marche toujours pas !

    $txt =~ s/^([0-9][0-9])\s/$1_/ge;
    damned

  12. #12
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par Franckinux
    oui d'accord j'ai compris tes exemples
    Malheureusement non... Dis-toi bien que le /e est un modificateur qu'on ne voit pas souvent, il n'est nécessaire ici que parce que l'une des parties de la regex vient de l'extérieur et on veut permettre d'y utiliser tout de même les variables $n...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    s/^([0-9][0-9])\s/$1_/g va donner $1_
    Non, ça va donner 01_, puisqu'ici on n'a pas de /e, la seconde partie est évaluée comme une chaîne de caractère entre guillemets doubles et $1 est donc interpolé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    s/^([0-9][0-9])\s/$1_/ge va donner 01_
    Non, ça va planter... A cause du /e, Perl va essayer d'interpréter $1_ comme s'il s'agissait d'une expression Perl, et va échouer (à cause du "_" qui n'est pas un opérateur valide en Perl). Si tu voulais utiliser /e, il faudrait faire quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    s/^([0-9][0-9])\s/"$1_"/ge
    Là l'expression à évaluer est "$1_", autrement dit c'est une simple chaîne de caractère, qui évaluée donne 01_ , c'est donc par cela que l'on va remplacer la première partie, ce qui nous convient.


    Dans notre cas, si nous mettions juste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    s/^([0-9][0-9])\s/$ARGV[1]/g
    $ARGV[1] sera interpolé, mais comme l'interpolation en Perl n'est pas récursive, s'il y a un nom de variable dans la chaîne de caractère $ARGV[1] on le retrouvera littéralement dans le résultat... On ne peut donc pas utiliser les $n dans la seconde partie avec cette méthode.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    s/^([0-9][0-9])\s/"$ARGV[1]"/ge
    donnera la même chose.

    Par contre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    s/^([0-9][0-9])\s/"\"$ARGV[1]\""/gee
    va d'abord s'évaluer en "le contenu de $ARGV[1]" puis être réévalué, donc il y aura à nouveau interpolation des variables dont le nom se trouvait dans $ARGV[1]. Mission accomplie !

    qq(qq($ARGV[1])) est juste une variante moins laide (à mon goût) de "\"$ARGV[1]\"".

    --
    Jedaï

  13. #13
    Membre du Club
    Profil pro
    DBA Oracle / MySQL / SQLServer
    Inscrit en
    Janvier 2005
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : DBA Oracle / MySQL / SQLServer

    Informations forums :
    Inscription : Janvier 2005
    Messages : 95
    Points : 54
    Points
    54
    Par défaut
    Merci pour ces explications.
    Je viens de tout relire depuis le début, je crois que j'ai compris grosso modo, j'ai confondu interprétation d'une chaine et d'une expression, je ne fais pas de difference entre interpolation et interprétation..., et :

    $ARGV[1] sera interpolé, mais comme l'interpolation en Perl n'est pas récursive...
    alors là
    il est évident qu'il me manque les bases...

    J'ai testé, effectivement ça fonctionne merci

    Pour les flags (g, e, et les autres), il faudrait pouvoir transformer une chaine de caractère en opérateur, c'est ça ? et ce n'est pas possible ?

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    427
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 427
    Points : 459
    Points
    459
    Par défaut
    en gros l'execution ne se fait qu'une seule fois.
    le /e est equivalent à un eval "", et on peu en enchainer plusieurs pour réinterpreter le resultat, comme si on enchainait des eval :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    my $a = '$b';
    my $b = '$c';
    my $c = 'bla';
     
    print $a, "\n"; # <=> print '$b'
    print eval($a), "\n"; # <=> print $b <=> print '$c'
    print eval(eval($a)), "\n"; # <=> print eval($b) <=> print $c <=> print 'bla'

  15. #15
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par Franckinux
    Pour les flags (g, e, et les autres), il faudrait pouvoir transformer une chaine de caractère en opérateur, c'est ça ? et ce n'est pas possible ?
    Tu peux, mais ce n'est pas sécurisé, et ce n'est pas une bonne ergonomie : ton application doit abstraire un minimum son utilisation par rapport au code sous-jacent : ton application doit savoir faire une opération précise, pas être un DSL (un domain specific language), ou alors on est dans une tout autre dimension.
    Mais le point important, c'est que tu ne veux pas que l'utilisateur puisse faire joujou avec des flags qui modifient la sémantique de l'opération que tu es en train d'effectuer (ou alors tu es effectivement en train de faire un langage de programmation) comme le font g et e (pour modifier ça, il vaut mieux permettre à l'utilisateur de passer des switchs au script, de façon à controler ce qui se passe).
    Note que les regex permettent d'insérer des flags à l'intérieur même de la regex, mais il ne s'agit pas de flag qui modifient la sémantique de l'opération, juste de ceux qui modifient ce qui va matcher la regex, autrement dit /i, /m, /s...
    La syntaxe qui fait ça est :
    Pour appliquer le flag /i à la regex dans les parenthèses.

    --
    Jedaï

  16. #16
    Membre du Club
    Profil pro
    DBA Oracle / MySQL / SQLServer
    Inscrit en
    Janvier 2005
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : DBA Oracle / MySQL / SQLServer

    Informations forums :
    Inscription : Janvier 2005
    Messages : 95
    Points : 54
    Points
    54
    Par défaut
    Encore désolé mais je comprend pas

    Mais pour revenir à l'ergonomie, les utilisateurs c'est essentiellement moi, et pi tous les gens qui veulent cet outils que je donnerais sans problème.
    Le but est de renommer massivement des fichiers avec des regexpr pour pouvoir faire du renommage assez puissant/complexe (je n'ai pas trouvé d'outil qui fessait ce que je souhaitai), la sécurité est donc à ma charge, de plus j'ai fait une option -show qui ne rennome pas mais affiche uniquement le résultat ainsi je ne ferais pas de bétises.

    Idéalement, je voudrais passer toute la regexpr mais ça ne fonctionne pas...
    Enfin je n'ai pas ré-essayé depuis que j'ai relu les messages du post.

    Mais je veux remplacer :
    $txt =~ s/$ARGV[0]/"\"$ARGV[1]\""/gee;
    par
    $txt =~ s/$ARGV[0]/"\"$ARGV[1]\""/$ARGV[2];
    Effectivement je pourrais faire des cases, mais le nombre de combinaisons est quand meme important donc le plus simple pour moi serait de pouvoir utiliser la var $ARGV[2].

    Je ne vois donc pas ce que je peux faire avec :
    (?i:regex)
    Eventuellement si l'un de vous peut me donner un exemple concret je comprendrais peut etre mieux

    Merci d'avance

  17. #17
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par Franckinux
    Effectivement je pourrais faire des cases, mais le nombre de combinaisons est quand meme important donc le plus simple pour moi serait de pouvoir utiliser la var $ARGV[2].
    Le nombre de combinaison ? Une seule option suffit : est-ce que tu veux remplacer toutes les occurences de la regex (/g) ou seulement la première. Rajouter un /e est inutile puisque tu peux faire ça avec ${} dans $ARGV[1]. Rajouter un /o devrait être fait de toute façon.
    Tous les autres flags sont accessibles avec la construction que je t'ai montré, dont je vais te donner un exemple simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ./ton_script.pl (?i:old) new
    Remplace toutes les occurences de "old", "Old", "oLd" ... par "new".

    NB : Cette construction permet même d'appliquer un flag à une partie seulement de la regex :
    matche old et Old, c'est tout.

    NB : Si c'est une application pour renommer en masse des fichiers, il va de toute façon falloir que tu fasses un système d'arguments pour pouvoir spécifier sur quels fichiers appliquer le renommage. Peut-être que faire un wrapper pour find2perl serait le meilleur choix.

    --
    Jedaï

  18. #18
    Membre du Club
    Profil pro
    DBA Oracle / MySQL / SQLServer
    Inscrit en
    Janvier 2005
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : DBA Oracle / MySQL / SQLServer

    Informations forums :
    Inscription : Janvier 2005
    Messages : 95
    Points : 54
    Points
    54
    Par défaut
    finalement oui mais on s'égare du sujet, ça ne correspond plus à ce que je veux faire car c'est du transcodage. en résumé : je veux juste appliquer récurssivement une regexpr sans trop m'élogner de la syntax des regexpr.

    $newfile =~ eval $ARGV[1];
    appelé par :

    rename.pl -show -expr="s/\s/_/g" -subdir "/mfs/data"
    où $ARGV[1] est -expr


  19. #19
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Si tu veux vraiment faire ça, il faut le faire ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    # $newfile est une copie du nom du fichier, que tu veux modifier
    # $regexp est la regex, récupéré par exemple avec Getopt::Long
    eval "\$newfile =~ $regexp;";
    if ( $@ ) {
      print "L'évaluation de votre expression a causé problème : $@...\n";
      exit 1;
    }
    finalement oui mais on s'égare du sujet, ça ne correspond plus à ce que je veux faire car c'est du transcodage.
    Ce que je te donnais correspondait exactement à ta question et n'avait rien à voir avec du transcodage (qui est effectué avec l'opérateur tr/// ou y///).

    --
    Jedaï

  20. #20
    Membre du Club
    Profil pro
    DBA Oracle / MySQL / SQLServer
    Inscrit en
    Janvier 2005
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : DBA Oracle / MySQL / SQLServer

    Informations forums :
    Inscription : Janvier 2005
    Messages : 95
    Points : 54
    Points
    54
    Par défaut
    je parle de transcodage au sens figuré c'est à dire des regexpr vers l'écriture de la ligne de commande :

    ./ton_script.pl (?i:old) new
    Donc ça marche mais pour les expressions un peut plus évoluées :

    -expr="s/^([0-9][0-9])\s/$1_/g"
    note : je ne met pas de e ou ee car je ne souhaite pas évaluer l'opération $1_ (_ n'est pas un opérateur)

    je retombe sur des fichiers avec des noms du genre _fichier alors que je veux 01_fichiers

    je suppose que les " " évaluent $1 avant la regexpr ?
    pourtant le \ devant $newfile n'est pas là pour empécher ça ?

    Désolé je suis peut etre un peut lourd mais je ne pense pas pouvoir acquérir les compétences en quelques jours

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. petit problème d'expression régulière
    Par stoyak dans le forum Langage
    Réponses: 5
    Dernier message: 16/05/2006, 12h20
  2. [regexp] petit problème d'expression régulière
    Par LE NEINDRE dans le forum Langage
    Réponses: 14
    Dernier message: 16/12/2005, 11h33
  3. Problème d'expression régulière
    Par SiM07 dans le forum Langage
    Réponses: 2
    Dernier message: 02/12/2005, 18h57
  4. Problème d'expression régulière
    Par Pymm dans le forum Général JavaScript
    Réponses: 15
    Dernier message: 11/10/2005, 16h04
  5. Problème d'expression régulière
    Par Neitsa dans le forum Général Python
    Réponses: 3
    Dernier message: 11/08/2005, 15h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo