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 avec locale


Sujet :

Langage Perl

  1. #1
    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 Problème avec locale
    Je suis en train d'essayer d'écrire un script qui a besoin de reconnaître correctement des mots en français, et donc les caractères accentués et autres.
    J'ai vu qu'il fallait utiliser la directive locale pour que Perl gère correctement cela, mais j'ai beau essayer, ça ne marche pas.
    À ce sujet, j'ai consulté la page de perldoc, qui indique plusieurs prérequis pour l'utilisation de locale :

    - Le système d'exploitation (dans mon cas, Ubuntu 7.04) doit supporter le système de "locale" :
    Il est mentionné que, si c'est le cas, la fonction setlocale() doit être mentionnée dans la documentation de la bibliothèque C. Je ne sais pas où se trouve cette dernière, donc je suis bien en peine de vérifier, mais je pense que ça doit être le cas, vu que toutes les applications que j'ai installées gèrent correctement la localisation.

    - Les définitions des "locale" que je veux utiliser doivent être installées :
    Je pense que c'est ce que j'obtiens en tapant "locale -a". Si c'est bien ça, c'est bon, j'ai ce qu'il me faut.

    - Perl doit savoir que le système de "locale" est supporté :
    J'ai fait comme indiqué, "perl -V:d_setlocale", et pas de souci, "define", ça roule (en plus, ça répond peut-être à mes doutes sur le premier prérequis, je ne sais pas).

    - Les variables d'environnement qui déterminent le "locale" doivent être correctement positionnées :
    en tapant "locale" tout court, j'obtiens ça :
    LANG=fr_FR.UTF-8
    LC_CTYPE="fr_FR.UTF-8"
    LC_NUMERIC="fr_FR.UTF-8"
    LC_TIME="fr_FR.UTF-8"
    LC_COLLATE="fr_FR.UTF-8"
    LC_MONETARY="fr_FR.UTF-8"
    LC_MESSAGES="fr_FR.UTF-8"
    LC_PAPER="fr_FR.UTF-8"
    LC_NAME="fr_FR.UTF-8"
    LC_ADDRESS="fr_FR.UTF-8"
    LC_TELEPHONE="fr_FR.UTF-8"
    LC_MEASUREMENT="fr_FR.UTF-8"
    LC_IDENTIFICATION="fr_FR.UTF-8"
    LC_ALL=
    J'en conclue que tout est ok, vu que c'est bien "fr_FR.UTF-8" que je veux utiliser.

    - L'application doit positionner son propre "locale" :
    Je ne suis pas sûr d'être concerné par ça, vu que c'est bien le "locale" par défaut que je veux utiliser. Donc, "use local;" devrait suffire, si j'ai bien compris (en me basant entre autres sur ce que j'ai pu voir sur ce forum).


    Bref, sauf erreur de ma part, toutes les conditions sont réunies. Pour m'en assurer, j'ai réalisé un petit script qui demande de taper une chaîne, et qui la découpe en ses différents éléments, considérant 1) les mots, et 2) tout le reste (caractère par caractère dans ce cas), et qui les affiche sur des lignes différentes.

    Voici ledit script :
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    #! /usr/bin/perl
    use strict;
    use warnings;
    use locale;
     
    #fonction de découpage de texte
    sub coupe
    {
       my ($texte)=@_;
    # utilisation dans un contexte de liste d'une regex avec /g, récupérant
    # soit des mots (\w+) soit des caractères n'appartenant pas à des mots.
       my @elements=$texte=~/\w+|./g;
       @elements;
    }
     
    # prompt et entrée de la chaîne
    print "Entrez la chaîne à traiter (vide pour sortir) : ";
    chomp(my $chaine=<STDIN>);
     
    while($chaine ne "")
    {
    #constitution de la liste avec &coupe
            my @liste=&coupe($chaine);
            print "Résultat du découpage :\n";
    #affichage du résultat
            print ((join "\n",@liste)."\n\n");
     
    # prompt et entrée de la chaîne
            print "Entrez la chaîne à traiter (vide pour sortir) : ";
            chomp($chaine=<STDIN>);
    }
    Voici maintenant ce que donne une exécution :

    Entrez la chaîne à traiter (vide pour sortir) : salut, toi
    Résultat du découpage :
    salut
    ,

    toi

    Entrez la chaîne à traiter (vide pour sortir) : vérification
    Résultat du découpage :
    v


    rification

    Entrez la chaîne à traiter (vide pour sortir) :


    Comme vous pouvez le voir, ce script fait exactement ce que j'attends de lui tant qu'on reste dans le domaine de l'ascii, mais débloque dès qu'on en sort.

    Qu'ai-je oublié ? Où ai-je fait erreur ? Que me manque-t-il pour que ça marche ? J'ai beau chercher, je ne vois pas.
    There's nothing like $HOME!

  2. #2
    Membre actif Avatar de mobscene
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    331
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 331
    Points : 234
    Points
    234
    Par défaut
    Ton script fonctionne très bien chez moi ( Windows XP )

    j'ai mis un screenshot avec ce post
    Images attachées Images attachées  
    Everybody have in their the potential to be their own god : Marilyn Manson

  3. #3
    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 mobscene
    Ton script fonctionne très bien chez moi ( Windows XP )

    j'ai mis un screenshot avec ce post
    Ben, apparemment non, il ne marche pas bien : il découpe les mots quand il y a des accents. Même problème que chez moi, en gros.
    There's nothing like $HOME!

  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
    Tu as sans doute un problème de différence de locale entre ton terminal et la locale que va utiliser Perl (le problème vient probablement de ton terminal). Essaie de trouver quel locale utilise ton terminal et de changer explicitement celle-ci dans ton script (ou le contraire, ça serait mieux...).
    Par exemple sous Windows le problème se pose assez systématiquement puisque le système en général utilise la "codepage 1252" (de l'unicode relativement standard) tandis que la console utilise par défaut la "codepage 850" (tu remarqueras que tous tes caractères accentués sortent mal, c'est dû à cette différence débile).
    Si je veux corriger le problème, j'utiliserais :
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    #! /usr/bin/perl
    use strict;
    use warnings;
    use POSIX qw(locale_h);
     
    setlocale(LC_ALL, 'French_France.850');
     
    use locale;
     
    #fonction de découpage de texte
    sub coupe {
       my ($texte)=@_;
       # utilisation dans un contexte de liste d'une regex avec /g, récupérant
       # soit des mots (\w+) soit des caractères n'appartenant pas à des mots.
       my @elements=$texte=~/\w+|./g;
       @elements;
    }
     
    # prompt et entrée de la chaîne
    print "Entrez la chaîne à traiter (vide pour sortir) : ";
    chomp(my $chaine=<STDIN>);
     
    while($chaine ne "") {
       #constitution de la liste avec &coupe
       my @liste=&coupe($chaine);
       print "Résultat du découpage :\n";
       #affichage du résultat
       print ((join "\n",@liste)."\n\n");
     
       # prompt et entrée de la chaîne
       print "Entrez la chaîne à traiter (vide pour sortir) : ";
       chomp($chaine=<STDIN>);
    }
    (Ouais non, en réalité je pense que ce genre de programme travaillerait plutôt avec des fichiers qui seront bien en codepage 1252, et si j'ai vraiment besoin de travailler avec la console, il y a des modules pour dialoguer avec la console Windows, généralement pour mes besoins personnels je me contente de changer la codepage de la console...)

    --
    Jedaï

  5. #5
    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 Jedai
    Tu as sans doute un problème de différence de locale entre ton terminal et la locale que va utiliser Perl (le problème vient probablement de ton terminal). Essaie de trouver quel locale utilise ton terminal et de changer explicitement celle-ci dans ton script (ou le contraire, ça serait mieux...).
    J'ai vérifié quel encodage utilise mon terminal, il est indiqué "Locale actuelle (UTF-8)". Vaille que vaille, j'ai essayé en mettant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    use POSIX qw(locale_h);
     
    setlocale(LC_ALL, 'UTF-8');
    mais, comme je m'y attendais, ça ne change rien au résultat.
    There's nothing like $HOME!

  6. #6
    Membre actif Avatar de mobscene
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    331
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 331
    Points : 234
    Points
    234
    Par défaut
    Citation Envoyé par Jedai
    Par exemple sous Windows le problème se pose assez systématiquement puisque le système en général utilise la "codepage 1252" (de l'unicode relativement standard) tandis que la console utilise par défaut la "codepage 850" (tu remarqueras que tous tes caractères accentués sortent mal, c'est dû à cette différence débile).
    [...]
    (Ouais non, en réalité je pense que ce genre de programme travaillerait plutôt avec des fichiers qui seront bien en codepage 1252, et si j'ai vraiment besoin de travailler avec la console, il y a des modules pour dialoguer avec la console Windows, généralement pour mes besoins personnels je me contente de changer la codepage de la console...)

    --
    Jedaï

    en fait windows utilise en interne UTF-16 a l'époque ou UTF-8 n'existait pas Win utilisait ucs-2 UTF-16 est utilisé car il apporte la compatibilité avec ucs-2 (pour les vieux programes) et utf-8

    la console utilise par contre un encodage oem chelou
    Everybody have in their the potential to be their own god : Marilyn Manson

  7. #7
    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
    En tout cas, j'ai pu m'assurer que ce n'est pas un problème de terminal, en faisant l'entrée depuis un fichier (en utf-8), pour le même résultat. C'est crispant.
    J'ai continué à chercher la cause du problème, mais je ne trouve toujours rien.
    There's nothing like $HOME!

  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
    Tu ouvres bien le fichier en tant qu'utf8 ? Avec '<:utf8' ?

    --
    Jedaï

  9. #9
    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
    Euh, non, je ne connais pas, ça. On fait comment ? Parce que là j'ai essayé ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    open IN,"<:utf8 $fichier" or die $!;
    ce qui me renvoie une erreur de fichier non trouvé, d'où je conclue que je n'ai pas bien compris quelle syntaxe utiliser.
    There's nothing like $HOME!

  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
    Il faut utiliser la forme à trois arguments de open() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    open my($in), '<:utf8', $fichier
      or die "Couldn't open $fichier : $!\n";
    Ou utiliser binmode(FH, 'utf8') sur le filehandle après l'avoir ouvert.

    --
    Jedaï

  11. #11
    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
    Il semble que le résultat est légèrement modifié. Voici mon nouveau script.
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    #! /usr/bin/perl
    use strict;
    use warnings;
    use locale;
     
    #fonction de découpage de texte
    sub coupe
    {
       my ($texte)=@_;
    # utilisation dans un contexte de liste d'une regex avec /g, récupérant
    # soit des mots (\w+) soit des caractères n'appartenant pas à des mots.
       my @elements=$texte=~/\w+|./g;
       @elements;
    }
     
    my ($entree,$sortie)=@ARGV;
     
    #ouverture des fichiers
    open IN,'<:utf8',"$entree" or die $!;
    open OUT,'>:utf8',"$sortie" or die $!;
     
    while(<IN>)
    {
            select OUT;
    #rappel de la chaine
            print "Chaine : ";
            print;
    #constitution de la liste avec &coupe
            my @liste=&coupe($_);
    #affichage du résultat
            print "\nRésultat du découpage :\n";
            print ((join "\n",@liste)."\n\n");
    }
    Le fichier d'entrée :
    salut, toi
    vérification


    Le résultat en sortie :
    Chaine : salut, toi

    Résultat du découpage :
    salut
    ,

    toi

    Chaine : vérification

    Résultat du découpage :
    v
    é
    rification


    Ce n'est toujours pas le résultat attendu, mais il y a effectivement un mieux.
    There's nothing like $HOME!

  12. #12
    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
    Bon, je renonce à la localisation pour le moment. Je chercherai de loin en loin comment résoudre mon problème. Si jamais je trouve, je posterai la solution ici.
    There's nothing like $HOME!

  13. #13
    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 travailles exclusivement avec de l'utf8 (et donc que tu contrôles ton environnement), mets "use utf8;" au début de ton script, tu pourras alors écrire ton script en utf8. Renseigne-toi aussi sur le support d'unicode dans les regex, par exemple : m/\p{IsWord}+|\P{IsWord}+/g devrait convenir.

    --
    Jedaï

  14. #14
    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
    Ah, OK, j'avais mal cherché dans mon Friedl. J'avais cru qu'on pouvait faire reconnaître les caractères localisés par \w. My bad.
    J'ai testé, et ça marche impeccable (même sans "use utf8;"). Encore que, vu que mon but est d'extraire des mots au sens grammatical du terme, c'est plutôt \p{L}+ que je dois utiliser (maintenant je sais où chercher ). D'ailleurs, c'est curieux, \p{IsWord} n'est pas mentionné dans le Friedl, pourtant riche en infos sur le dialecte de regex de Perl. Comme quoi, il ne faut pas se fier à un seul bouquin...
    There's nothing like $HOME!

  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 Schmorgluck
    Ah, OK, j'avais mal cherché dans mon Friedl. J'avais cru qu'on pouvait faire reconnaître les caractères localisés par \w. My bad.
    On peut, on le fait, mais visiblement il y a un petit problème sur ton système... Je n'ai pas idée de ce qu'est exactement ce problème, mais au moins l'utilisation de propriété Unicode est portable du moment que tu es sûr que les données seront en Unicode.

    Citation Envoyé par Schmorgluck
    J'ai testé, et ça marche impeccable (même sans "use utf8;").
    Oui le "use utf8" n'est pas indispensable (pour Perl 5.8 en tout cas), mais il te permet d'écrire ton script en utf8 (chaînes en utf8, noms de symboles en utf8 (encore que là j'éviterais à ta place)), ce qui est sympathique dans un environnement "tout utf8".

    --
    Jedaï

  16. #16
    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 Jedai
    On peut, on le fait, mais visiblement il y a un petit problème sur ton système...
    Tu penses qu'il serait judicieux de ma part de poster à ce sujet dans le forum Linux ?
    There's nothing like $HOME!

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

Discussions similaires

  1. [EasyPHP] EasyPHP 1.8 ... problème avec les pages en local !
    Par Franck.H dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 3
    Dernier message: 06/04/2007, 14h12
  2. Problème avec connexion au réseau local
    Par eon-of-the-scorn dans le forum Windows XP
    Réponses: 6
    Dernier message: 24/03/2007, 19h06
  3. [EJB] Problème avec l'interface locale d'un bean
    Par clement42 dans le forum Java EE
    Réponses: 2
    Dernier message: 07/01/2006, 09h24
  4. problème avec le disque local
    Par suiss dans le forum Windows XP
    Réponses: 16
    Dernier message: 30/11/2005, 23h11
  5. problème avec load data local
    Par afrikha dans le forum Débuter
    Réponses: 2
    Dernier message: 28/10/2005, 18h36

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