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 :

chaînes de caratères remplacer


Sujet :

Langage Perl

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 47
    Points : 29
    Points
    29
    Par défaut chaînes de caratères remplacer
    Bonjour,

    J'ai une chaîne de caractères : Lire:des:Histoires:droles
    et j'aimerais remplacer uniquement avant le premier deux-points par le mot Ecrire.

    Je débute sous Perl, j'ai pensé aux expressions régulières ...

    Merci de votre aide.

  2. #2
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Quelque chose comme ceci devrait faire l'affaire, mais il faudrait que tu détailles un peu plus ton besoin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $texte =~ s/^\w(:)/Ecrire$1/;
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  3. #3
    Membre à l'essai
    Homme Profil pro
    BTS Systeme Numérique et Informatique Réseau . (2014-2016)
    Inscrit en
    Juin 2015
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : BTS Systeme Numérique et Informatique Réseau . (2014-2016)
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2015
    Messages : 30
    Points : 23
    Points
    23
    Par défaut
    Après tu peux aussi séparer ta chaine pour les mettre dans un tableau.


    Code perl : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    my $chaine="Lire:des:Histoires:droles";#Ta chaine de caractère
    my @tab=split(/:/,$chaine);#Le caractère de séparation est ":"
    $tab[0]="Ecrire";#Tu remplaces "Lire" par "Ecrire"
    print "@tab";#Et tu affiches la nouvelle chaînes de caractère
    #Cela affiche :"Ecrire Des Histoires droles"
    <>;

  4. #4
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Oui avec un remplacement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $txt =~ s/^[^:]*/Ecrire/;
    (^ marque le début de la chaîne, [^:] est une classe de caractères qui exclue les deux-points, * est un quantificateur qui signifie zéro ou plusieurs fois.)


    ou en passant par split:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    my @tab = split(/:/, $txt, 2); # le 3e paramètre limite le nombre de résultats à 2
    $txt = "Ecrire:" . $tab[1];
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  5. #5
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Franchement, un split pour quelque chose d'aussi simple à faire avec une expression régulière, c'est un peu de l'overkill.

  6. #6
    Membre averti
    Avatar de magicshark
    Homme Profil pro
    Dans une SS2I donc pas que JAVA
    Inscrit en
    Octobre 2011
    Messages
    133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dans une SS2I donc pas que JAVA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2011
    Messages : 133
    Points : 320
    Points
    320
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my $txt = 'Lire:des:Histoires:droles';
    $txt =~ s/Lire/Ecrire/;
    print $txt;
    Si ta chaîne est toujours "Lire:Des:Histoires:Droles"
    Pourquoi faire simple quand on peut faire compliqué.

  7. #7
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    De l'overkill non, car il n'y a pas de mise en œuvre d'un outil surpuissant ou disproportionné par rapport à la tâche à accomplir, moins straight forward (droit au but) peut être.
    Ça peut paraître moins direct parce que moins concis (cela dit on peut l'écrire en une ligne) et parce que les étapes de l'opération sont plus apparentes, mais il ne doit pas y avoir une grande différence entre les deux (recherche, chaînes temporaires, concaténation, affectation du résultat => toutes ces étapes sont bien présentes lors d'une substitution mais la plupart sont masquées).

    De plus, dans un contexte de champs séparés par un délimiteur (ici littéral donc trouvé très rapidement par un algorithme de recherche rapide, sans même utiliser la marche normal du moteur), utiliser split n'a rien d'incongru quand bien même le champ visé serait le premier.

    À noter que dans tout autre langage que Perl qui fait la part belle au regex, les remarques auraient été plutôt dans l'autre sens (pourquoi sortir les regex quand on peut faire comme ci ou comme ça) avec plus ou moins de raison. Par exemple, si je devais faire la même chose en shell, mise à part l'utilisation du parameter expansion:$txt="Ecrire"${txt#*:} ou $txt=${txt/*([^:]):/Ecrire:} avec Bash qui reste la solution la plus concise, je ne sais pas sur quoi mon choix se serait porté entre cut (je ne sortirais probablement pas awk pour ça) et sed.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  8. #8
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    En fait, CosmoKnacki, je répondais plutôt à SupraPF qu'à toi. Pour 2 raisons, d'abord tu as aussi proposé une regex, et, après tout TIMTOWTDI. La seconde raison est que tu as utilisé un split avec trois paramètres, le 2 passé en argument permet de ne pas splitter toute la chaîne, et la concaténation finale n'utilise que 2 sous-chaînes. Du coup, ta solution est sans doute efficace. Celle proposée par SupraPF l'était moins (plus de travail au split et plus à la concaténation).

    Il m'arrive de "détourner" split de son objet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    my $last_field = (split /;/, $_)[-1];
    Alors qu'une regex ancrée sur la fin de chaîne serait peut-être meilleure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $last_field = $1 if /;(\w+)$/;

  9. #9
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Suite à mon dernier post, je me suis livré à quelques benchmarks (avec Benchmark::timethese) pour les deux voies histoire de mesurer l'impact que pouvait avoir le fait d'utiliser une chaîne littérale pour split (et donc de court-circuiter la marche du moteur de regex avec un algorithme de recherche rapide. (Bien sûr, dans la réalité, je doute qu'il y ait besoin de faire plus d'un million de fois le même remplacement. Ça reste des résultats de benchmark sur une chaîne très courte).

    Par rapport à une substitution le gain reste certes faible 4 à 5% (Autant dire que pour des remplacements sporadiques c'est imperceptible.), mais il est toujours au rendez-vous, et ce bien que la pattern de substitution soit ancrée au début de la chaîne. Mais il suffit de changer /:/ en /[:§]/ pour que la tendance s'inverse. Par contre changer /:/ en /:d/ ralentit à peine le split, car on reste avec une chaîne littérale.

    Du coup, j'ai également tester les deux propositions pour obtenir le dernier champs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    use Benchmark;
    use strict;
    use warnings;
     
    my $count = shift || die "Need a count!\n";
     
    sub splitou {
        my $txt = "C;était;l;hôtel;d;Abyssinie;et;du;Calvados;réunis";
        my $last_field = (split /;/, $txt)[-1];
    }
     
    sub matchou {
        my $txt = "C;était;l;hôtel;d;Abyssinie;et;du;Calvados;réunis";
        my $last_field = $1 if $txt =~ /;([^;]*)$/;
    }
     
     
    timethese ( $count, {'Method splitou' => '&splitou', 'Method matchou' => '&matchou'});
     
    exit;
    Et là, malgré le fait que la pattern de la substitution soit ancrée à droite avec $ (ce qui ne change pas grand chose quand on y pense car le moteur de regex avance de gauche à droite, donc on pourrait mettre (?!choucroute garnie) à la place que ce serait pareil), le split avec sa pattern littérale est 2 à 3 fois plus rapide. Par contre je ne parierai pas sur sa consommation mémoire.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  10. #10
    Membre averti
    Avatar de magicshark
    Homme Profil pro
    Dans une SS2I donc pas que JAVA
    Inscrit en
    Octobre 2011
    Messages
    133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dans une SS2I donc pas que JAVA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2011
    Messages : 133
    Points : 320
    Points
    320
    Par défaut
    Jolie débat cependat j'ai l'impression qu'on perd de vue l'objectif principal qui est :
    Citation Envoyé par crow56 Voir le message
    Bonjour,

    J'ai une chaîne de caractères : Lire:des:Histoires:droles
    et j'aimerais remplacer uniquement avant le premier deux-points par le mot Ecrire.

    Je débute sous Perl, j'ai pensé aux expressions régulières ...

    Merci de votre aide.
    en lisant celà avec un esprit plus ou moins professionnel, habitué et avec du ecul on recherche à faire des choses dynamique qui sont en fonction de ceci, celà.
    Cependant on perd de vu les cose les plus simple. Le problème que pose crow, est un problème qui se trouve dans le tuto perl ($v =~ s/voiture/pieds/; )

    J'en déduit que du coup la solution la plus simple pour quelqu'un qui débute en perl serait donc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $txt =~ s/Lire/Ecrire/;
    Mais Jolie débat
    Pourquoi faire simple quand on peut faire compliqué.

  11. #11
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Je ne suis pas du même avis que toi, magicshark, et je rejoindrais CosmoKnacki. J'explique mes raisons :
    - en général, le posteur "débutant" imagine des solutions locales à ses problèmes : ici, les regexp. Cependant il est très rare qu'il ait une vision plus globale de son problème (et notamment, étant débutant, il n'imagine pas toujours les différentes solutions possibles à son problème local). Dans le cas présent, le fait d'avoir une liste de champs séparés par un : (le séparateur), me laisse penser que dans le reste du traitement, on cherchera aussi à utiliser les autres champs (ce n'est pas sûr, mais c'est probable).
    - la question soulevée ne semble pas générer de problème de performance (d'ailleurs, "a priori", on ne devrait jamais avoir à se préoccuper des performances, mais se préoccuper d'abord du fonctionnel, et de la maintenabilité).

    Du coup, la solution du split (même à 2 paramètres), ne me parait pas du tout inappropriée, et elle est en tout cas
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  12. #12
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 280
    Points : 12 729
    Points
    12 729
    Par défaut
    Bonjour,

    Pas spécialement pour la perf, mais juste une autre vision pour faire la même chose:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my $txt = 'Lire:des:Histoires:droles';
    $txt = join ":","Ecrire",$txt =~ m/:(.*)/;
    print $txt;
    Cordialement.

Discussions similaires

  1. Problème tableau de chaînes de caratères
    Par developppez dans le forum C
    Réponses: 4
    Dernier message: 07/05/2007, 20h33
  2. Problème tableau de chaînes de caratères
    Par LinuxUser dans le forum C
    Réponses: 49
    Dernier message: 02/05/2007, 10h39
  3. [Smarty] Changement de chaîne de caratères
    Par FracMaster dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 27/04/2007, 15h59
  4. Réponses: 3
    Dernier message: 29/09/2006, 16h27
  5. supprimer les espaces dans une chaîne de caratères.
    Par Empty_body dans le forum Langage
    Réponses: 2
    Dernier message: 12/09/2006, 18h43

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