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 :

Suppression d'un caractère peu commun dans une chaîne de caractères issue d'Excel


Sujet :

Langage Perl

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2013
    Messages : 10
    Points : 5
    Points
    5
    Par défaut Suppression d'un caractère peu commun dans une chaîne de caractères issue d'Excel
    Bonjour,

    Désolé d'avoir donné un titre pas très envoutant ou précis à ce post, mais rien d'autre ne m'est venu sur le moment.
    Si quelqu'un a une idée, au pire, j'éditerai ...
    Je vous détaille donc le problème.


    Tout d'abord, je vous situe le contexte : j'ai un fichier nommé donnees.xls, qui est un fichier .txt ayant été renommé en .xls ; c'est un fichier texte, ayant pour séparateur des tabulations, mais s'ouvrant dans excel.

    Sur le lieu de mon stage, une machine génère ce fichier. Je ne peux pas faire changer la mise en forme des informations.

    Venons au problème ; j'ai récupéré toutes les données qui m'intéressaient via un script perl (pour le moment je bosse avec la console), et parmi ces données se trouvent une colonne assez embêtante.
    Elle contient des nombres décimaux (deux chiffres après la virgule) allant de plusieurs milliers à plusieurs centaines de milliers. Il est possible que certains de ces nombres soient même plus grand qu'un million.

    A première vue, excel génère des espaces tous les (10^3)^x --> milliers, millions...
    Prenons comme valeur récupérée 150 000,00
    Lorsque je récupère cette valeur, si je l'affiche, elle sera sous la forme 150á000,00.
    Que je la récupère dans une chaîne de caractères ou dans une variable numérique, rien n'y est changé.
    J'ai donc tenté des regex pour enlever " á " à la chaîne, idem pour enlever tous les espaces de la chaîne (au cas où ce soit uniquement l'affichage qui pose problème).

    Après test (merci les regex), il est apparu que la valeur retournée n'était pas considérée comme numérique.

    j'imagine que l'espace visible sur la feuille excel doit être généré par la machine, ou bien par excel.
    --> j'ai voulu modifier une des colonnes manuellement pour obtenir un nombre dépassant le million, et l'espace ajouté à la main a correctement été affiché, mais pas l'autre.



    Après réflexion, j'ai trouvé deux solutions pour me débarrasser de ce foutu caractère, et encore, une seule me plaît.

    - La première, la plus absurde, supprimer les espaces dans le fichier excel via script, ... si ça veut bien marcher, puisque l'expression régulière que j'ai utilisée n'a pas donné le résultat attendu.

    - La deuxième est la suivante : obtenir la longueur de chaque chaîne, et ensuite :
    Si la longueur de la chaine est de 8 caractères (soit deux chiffres après la virgule, la virgule, trois chiffres, le caractère, et un chiffre de milliers) à 10, supprimer le 7ème caractère en partant de la fin, et si elle est d'au moins 11 caractères, supprimer le 10ème en partant de la fin.
    Pas besoin de faire une boucle avec des %3, les chiffres en questions n'atteindront jamais les milliards

    Mais, cette solution implique de devoir trifouiller un minimum le code si on décide de rajouter des chiffres après la virgule, par exemple.

    C'est pour ça que je viens vous supplier ô humbles collègues développeurs (ou non! ) de me dire si vous avez quelque chose de mieux que ma deuxième solution (en espérant qu'elle marche, j'avoue que je ne l'ai pas encore testée).

    A titre d'information, je n'ai commencé le perl qu'hier... il est donc possible que des notions basiques qui auraient pu me sortir d'affaire me soient inconnues. Si c'est le cas, je m'en excuse.
    (Enfin j'ai fouillé rapidement la FAQ et Google sans trouver de problème pareil donc... =)


    Merci d'avance à vous !
    Que ce soit pour la lecture du pavé, ou les réponses apportées

    Cordialement.

  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
    Ton problème ressemble à un problème d'encodage : le caractère lu dans Excel n'a pas le même encodage que celui par défaut des chaines perl.

  3. #3
    Membre du Club
    Homme Profil pro
    BioInformaticien
    Inscrit en
    Décembre 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : BioInformaticien
    Secteur : Service public

    Informations forums :
    Inscription : Décembre 2012
    Messages : 49
    Points : 63
    Points
    63
    Par défaut
    mmh ça ressemble à un caractère qui "apparait comme étant" un à mais qui n'en est pas un... C'est l'une des grandes joies des modifications de format.

    si ta valeur est facile a isoler du reste de ta ligne (tu as dis qu'elle était encadrée de tabulation ? ) tu peux par exemple :
    -faire un split au niveau de la virgule (tu auras donc deux variables, une avec les décimales, et l'autre avec les unités et donc tes à).
    -Sur les unités, tu peux faire un subst (substring) qui supprime le 4ème, 7eme, etc... caractère en partant de la fin. Vu que tu n'as plus de décimales, les gens peuvent toujours rajouter des nombres après la virgule.

    Par contre fais attention a ce qu'une virgule ne soit pas soudainement changée en point par excel! (ou prévois cette situation)

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2013
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par Philou67430
    Ton problème ressemble à un problème d'encodage : le caractère lu dans Excel n'a pas le même encodage que celui par défaut des chaines perl.
    C'est bien possible, j'avoue que cet après-midi, j'avais la tête dans le code, le code, le code... et je n'ai pas porté d'attention particulière à ça.

    Je verrai ça demain, mon code est au boulot.

    Citation Envoyé par trex7g2
    faire un split au niveau de la virgule (tu auras donc deux variables, une avec les décimales, et l'autre avec les unités et donc tes à).
    Pas bête ! Simple pourtant, mais pas bête
    Si jamais ce n'était pas un problème d'encodage, j'opterai (normalement) pour cette solution.

    Je mettrai à jour tout ça dès que ça sera testé.

    Merci à vous deux pour vos réponses !

    Bonne soirée.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2013
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    Après quelques tentatives d'encodage qui furent un échec, je me suis donc rabattu sur le principe de la deuxième solution.

    J'en ai profité pour convertir ma virgule en point, j'oubliais que MySQL digère difficilement les virgules pour les décimaux...

    Voilà le code utilisé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # $champ correspond à la valeur à modifier :123á456,78
    # je rappelle que  $champ =~ s/á//g;  ne fonctionne pas
     
    my @temp = split(/,/,$champ);
     
    # On ne conserve que les chiffres
    $temp[0] =~ s/[^[:alnum:]]//g;
    $champ = $temp[0].".".$temp[1];
     
    print "$champ \n";
    Ce qui marche impeccablement bien.
    * met le sujet en résolu *

    Après... pour ma culture personnelle, niveau 'consommation de ressources', y'a pas plus léger qu'une regex?
    Il y a sûrement substr(), mais j'ai un peu de mal à comprendre son fonctionnement (mais ceci est une autre histoire...).
    Ici, 300 à 500 lignes sont concernées en moyenne, donc c'est pas la mort d'utiliser une méthode un peu plus lourde.

    Je vous remercie encore.

    Owl'

  6. #6
    Membre confirmé
    Avatar de Schmorgluck
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    371
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2006
    Messages : 371
    Points : 558
    Points
    558
    Par défaut
    Citation Envoyé par Owleur Voir le message
    Après... pour ma culture personnelle, niveau 'consommation de ressources', y'a pas plus léger qu'une regex?
    Il y a sûrement substr(), mais j'ai un peu de mal à comprendre son fonctionnement (mais ceci est une autre histoire...).
    Ici, 300 à 500 lignes sont concernées en moyenne, donc c'est pas la mort d'utiliser une méthode un peu plus lourde.
    Pas vraiment.
    Déjà, substr ne pourrait pas te servir, vu que tu ne connais pas à l'avance la structure de ta chaîne.
    Ta regex est fixe, et ne nécessite donc qu'une seule compilation. De plus, elle est très simple, et perl utilise des optimisations très efficaces. Donc, en terme de performances; je doute qu'on puisse faire mieux.

  7. #7
    Membre du Club
    Homme Profil pro
    BioInformaticien
    Inscrit en
    Décembre 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : BioInformaticien
    Secteur : Service public

    Informations forums :
    Inscription : Décembre 2012
    Messages : 49
    Points : 63
    Points
    63
    Par défaut
    une substr qui te conviendrait serait quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if length($temp[0]>3){
        $temp[0]=substr($temp[0],0,length($temp[0])-4).substr($temp[0],length($temp[0])-3,3)}
    et ça ne fonctionne plus dès que tu as un million... donc même si c'est un tout petit peu plus rapide je préfère très largement ta regexp (fonctionnelle, efficace, transferable en cas de changement d'échelles.... )

    ps : il doit y avoir aussi quelque chose qui supprime directement le 4eme caractère mais je ne me rapelle plus exactement de la structure de la fonction... quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    substr($temp[0],length($temp[0])-4,1)="";

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2013
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par trex7g2
    une substr qui te conviendrait serait quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if length($temp[0]>3){
        $temp[0]=substr($temp[0],0,length($temp[0])-4).substr($temp[0],length($temp[0])-3,3)}
    Voilà, c'était à quelque chose de ce genre-là que je pensais... sauf que j'arrivais pas vraiment à l'utiliser, cerveau embrouillé peut-être

    Ok, je prends note et je retiens, merci à vous tous

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [WebI XiR2] Suppression d'un espace dans une chaîne de caractères
    Par SGA99 dans le forum Débuter
    Réponses: 6
    Dernier message: 02/12/2010, 17h12
  2. Vérifier si une chaîne de caractère est contenu dans une autre
    Par Marvelll dans le forum Débuter avec Java
    Réponses: 7
    Dernier message: 22/02/2010, 14h54
  3. Réponses: 5
    Dernier message: 25/02/2008, 14h34
  4. ?> dans une chaîne de caractéres
    Par nebule dans le forum Langage
    Réponses: 8
    Dernier message: 15/11/2005, 15h01
  5. Réponses: 4
    Dernier message: 23/06/2004, 09h51

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