Menu

Condition sur dernier caractère d'une chaine[PERL] [Résolu/Fermé]

Messages postés
20
Date d'inscription
vendredi 30 mars 2018
Statut
Membre
Dernière intervention
22 août 2018
-
Bonjour,

Je viens chercher de l'aide ici car j'ai un petit problème auquel je n'ai pas trouvé de solution sur les forums.

J'ai un un fichier contenant des noms d'isotopes. Mon problème est que certains de ces isotopes ont un petit "F" à la fin pour "Fondamental" qui me gène. J'aimerai m'en débarrasser. Alors je sais déjà que j'utiliserai "chop()". Mais mon problème est dans la condition. Je ne sais pas comment faire en sorte que mon script efface le dernier caractère de l'isotope SEULEMENT si ce dernier caractère est un "F".

J'imagine que c'est très simple ..

Merci d'avance !
Afficher la suite 

3 réponses

Meilleure réponse
Messages postés
5169
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
18 juillet 2019
785
1
Merci
Bonjour am33450,

Oui, c'est assez simple avec une regexp comme cela :

#!/usr/bin/perl

use strict;
use warnings;

my $st = "ISOTOPEf";

print "avant st = $st\n";
$st =~ s/f$//;
print "après st = $st\n"; 

Dal

Dire « Merci » 1

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 54723 internautes nous ont dit merci ce mois-ci

Messages postés
20
Date d'inscription
vendredi 30 mars 2018
Statut
Membre
Dernière intervention
22 août 2018
0
Merci
Bonjour et merci Dal,

Mon problème est surtout dans la condition de la boucle, j'avais essayé ça :



if (substr($iso,-1,1) == "F"){
chop($iso);
}



Ca avait l'air de marcher car ça retirait le "F" en fin de nom mais ça a également enlevé les "M" à la fin du nom de certains isotopes. Or pour ces isotopes là, je ne veux pas supprimer ce "M". Connais tu un autre moyen de n'enlever que les F ?

Merci d'avance,
am
[Dal]
Messages postés
5169
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
18 juillet 2019
785 -
oui, utiliser mon code qui tient en 1 ligne effective au lieu de tes 3 lignes utilisant un opérateur de comparaison inadéquat.

$iso =~ s/f$//;

(si par un petit "F" comme tu disais dans ton message initial tu veux bien dire la lettre "f" minuscule)

cette regexp signifie : pour la variable $iso cherche si à la fin il y a "f", et si oui, remplace cela par rien du tout (le symbole
$
dans les regexp Perl étant utilisé pour signifier la fin de ligne)

la partie recherchée est après le
s
(comme search) et entre les deux premiers slashs, et la partie qui remplace est entre les deux derniers slashs... c'est la façon de faire ce genre de choses en Perl de manière naturelle et expressive

si tu dis "petit "F", mais qu'en fait le terme "petit" est une désignation affectueuse pour ce caractère, et que c'est un "F" majuscule que tu veux supprimer (et n'opérer aucune suppression s'il y a un "f" minuscule ou toute autre caractère), comme le laisse supposer le code que tu postes ci-dessus, tu fais juste :

$iso =~ s/F$//;

et si tu veux supprimer la lettre F finale, qu'elle soit en minuscule ou majuscule, tu fais :

$iso =~ s/F$//i;

ce qui applique à la regexp le modificateur "i" pour insensible à la casse.


Utiliser Perl sans utiliser les regexp, c'est un peu comme utiliser une voiture avec une boite à 5 vitesses et une marche arrière et choisir de ne conduire qu'en marche arrière :-D

Tu peux apprendre à t'en servir progressivement, sur des cas simples comme celui-ci et maîtriser au fur et à mesure des usages plus poussés. Cet apprentissage te servira énormément et pas uniquement avec le langage Perl, de nombreux langages utilisant les expressions rationnelles dérivées de Perl ou se voulant compatibles Perl, incluses dans le langage ou utilisables au travers de la populaire bibliothèque "Perl Compatible Regular Expressions" (PRCE).

Pour un aperçu : https://www.regular-expressions.info/tools.html
[Dal]
Messages postés
5169
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
18 juillet 2019
785 -
sinon, dans ton code, tu utilises l'opérateur d'égalité numérique
==
, alors que tu compares des chaînes (un ou plusieurs caractères pouvant résulter de substr). L'opérateur d'égalité pour les chaînes est
eq
... vois :

https://perldoc.perl.org/perlop.html#Equality-Operators
[Dal]
Messages postés
5169
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
18 juillet 2019
785 -
note qu'il est fortement recommandé en Perl moderne d'utiliser les directives :

use strict;
use warnings;

que tu devrais mettre au début de ton code (ce que je pense que tu ne fais pas vu que tu ne semblais pas pour la raison qui suit).

En faisant cela, Perl se serait plaint de l'erreur suivante :
Argument "F" isn't numeric in numeric eq (==)
lors de l'exécution.

Rend toi service à l'avenir et utilise ces directives :-)
Messages postés
20
Date d'inscription
vendredi 30 mars 2018
Statut
Membre
Dernière intervention
22 août 2018
0
Merci
Merci !

En effet je comprends mieux toute la puissance de ce langage si on peut en une ligne faire tout ça ! Merci pour la doc sur les regexp.

Ça marche parfaitement.
[Dal]
Messages postés
5169
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
18 juillet 2019
785 -
Super !

Le lien que j'ai donné est pour te donner un aperçu du nombre de langages ou d'outils où une connaissance des expressions rationnelles te sera utile.

Pour apprendre les regexp, je conseillerais plutôt :

- le tutoriel issu de la documentation officielle de Perl : https://perldoc.perl.org/perlretut.html qui est très bien fait (comme le reste de la doc Perl), mais peut être trop détaillé pour un débutant complet

- des tutoriels en ligne plus doux, comme : http://www.learn-perl.org/en/Regular_Expressions ou https://perlmaven.com/introduction-to-regexes-in-perl

- des outils d'aide à la mise au point de regexp, comme celui-ci : http://www.weitz.de/regex-coach/

et des pense-bête comme http://jkorpela.fi/perl/regexp.html sont utiles pour une information très concentrée lorsqu'on a acquis les bases.