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 :

extraction des données- foreach


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 51
    Par défaut extraction des données- foreach
    Bonjour,

    Je veux extraire les noms de ville, mais dans les données, on trouve aussi les noms d'université portant les noms de ville, par ex "University of New York" ou "National Laboratory New York", donc dans ce cas-là, je veux que le programme n'extrait pas ce nom de ville qui suit le mot "University" ou "Laboratory".

    voici mon code
    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
     
     if ($ligne=~/(at|) ($ville)(( \d+)|( \-)|(,? [A-Z]{2})|(,?$)|( \/)|(, [A-Za-z]+)|( \())/i)
    {	$iscity = TRUE;
    	@mots = split (/ /, $ligne);
    	if ($iscity == TRUE)
    	{   foreach $mot (@mots)
    		{	if (($mot eq "National")||($mot eq "of")||($mot eq "de")||($mot eq "University"))		    
                            {$iscity = FALSE;
                            }
    		}
    				  print "<VILLE>$2</VILLE>\n"; 
                                      print SORTIE "<VILLE>$2</VILLE>\n";
              }
    			 #print "<VILLE>$2</VILLE>\n"; 
    			#print SORTIE "<VILLE>$2</VILLE>\n";
    }
    Ce programme parcourt une liste de noms de ville dans un fichier puis le répertoire des données. Les résultats de sortie, le programme imprime tjs le premier ville qui a trouvé dans les données, il fait un boucle.

    Pourriez-vous m'aider comment je peux extraire les vrais noms de ville, mais pas les noms d'université qui portent aussi le nom de ville.

    Merci beaucoup

  2. #2
    Membre chevronné
    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
    Par défaut
    Je ne comprends pas bien à quoi sert ta variable $iscity et donc le deuxième "if". En fait, si, je comprends : ils ne servent à rien. Qu'as-tu essayé de faire, au juste ? Es-tu sûr d'avoir mis ton "if" là où il faut ?

    Bon, c'est secondaire pour ton problème, parce que moi, tout ce que je vois, c'est que tu devrais purement et simplement écarter les lignes où la partie contenant éventuellement un nom de ville (c'est à cela, je suppose, que sert la variable $ville qu'on voit dans ta regex) commence par "University" ou "National Laboratory". Puisqu'apparemment seule cette partie de la ligne t'intéresse, tu devrais, passé le premier test, utiliser la variable $2 pour récupérer le contenu de la deuxième parenthèse capturante. Puis faire un test pour le reste de ton traitement, basé uniquement sur ce contenu.
    Ça pourrait donner quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     if ($ligne=~/(at|) ($ville)(( \d+)|( \-)|(,? [A-Z]{2})|(,?$)|( \/)|(, [A-Za-z]+)|( \())/i)
    {
    	$nom = $2;
     
    	unless ($nom=~/^(?:university|national laboratory)/i)
    	{
    				  print "<VILLE>$nom</VILLE>\n"; 
                                      print SORTIE "<VILLE>$nom</VILLE>\n";
              }
    }
    Ceci dit, ça n'explique pas ton problème de boucle. Rien de ce que tu nous as montré n'est susceptible de causer une boucle infinie. Le problème doit venir d'une autre partie du code. Qu'utilises-tu pour lire le fichier ? L'opérateur diamant ?

  3. #3
    Expert confirmé
    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
    Par défaut
    Il faut voir quel niveau réel de précision tu veux. Par exemple tu peux faire un filtrage par ligne, en ne cherchant de nom de ville que dans les lignes qui ne contiennent pas de mot suspects. Tu auras alors un fort taux de faux négatifs mais très peu de faux positifs.
    Tu pourrais également chercher les mots suspects et éliminer tout un intervalle autour d'eux, de deux ou trois mots. Tu trouveras sans doute bien plus d'occurences ainsi, mais certaines seront fausses à moins que tu ne choisisse un intervalle de "méfiance" très étendu, mais alors tu retombes dans le premier cas, avec une complexité bien plus grande... A toi de voir si le jeu en vaut la chandelle.

    Evidemment la meilleure solution serait de procéder à une analyse sémantique basique sur le texte, et d'utiliser une logique floue pour établir le pourcentage de chance que chaque nom de ville ne soit qu'une partie d'un ensemble comme un nom d'établissement scolaire. Mais là on parles d'un projet de recherche, plus d'un simple programme utilitaire !!

    Il y a également des solutions intermédiaires, batardes, où tu t'appuies sur quelques heuristiques pour établir ton opinion sur une occurrence donnée. Mais cette option doit être soigneusement réfléchie de façon à pouvoir rajouter ou modifier l'une des heuristiques employées aisément, et sans perturber la structure du programme, sinon tu te retrouveras vite avec un bordel inommable !

    Alors, à quel point as-tu besoin que ta solution soit fiable ? Dis-toi bien que tu seras de toute façon obligé de te reposer sur des heuristiques qu'elles soient simples ou complexes.

    --
    Jedaï

  4. #4
    Membre chevronné
    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
    Par défaut
    Faut dire aussi qu'on manque d'infos sur la structure des données à traiter. Et je me suis penché (sans tomber) sur la grosse regex du premier "if", et plusieurs choses m'ont frappé (aïe !) :
    - Elle est bourrée de parenthèses inutiles, vu que l'alternative a priorité sur tout sauf les parenthèses.
    - Il y a une classe [A-Za-z] alors qu'elle est traitée avec l'option d'insensibilité à la casse.
    - Un caractère '-' échappé on ne sait pourquoi.

    Fort de ces remarques, ladite regex peut-être modifiée comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /(?:at|) ($ville)(?: \d+| -|,? [A-Z]{2}|,?$| \/|, [A-Z]+| \()/i
    C'est quand même un poil plus sobre.
    Par ailleurs, sur les trois paires de parenthèses qui restent, une seule a besoin d'être capturante, autant changer les autres par des non-capturantes (ce que j'ai fait), c'est pas une énorme optimisation, mais il n'y a pas de petits profits, et c'est une bonne habitude à prendre. Du coup, dans le code qui suit, il faut bien sûr utiliser $1 et non $2.

    Avec plus d'infos sur les fichiers parcourus, il serait peut-être possible de faire encore mieux, notemment en termes d'optimisation.
    En effet, plusieurs problèmes se posent en la matière avec cette regex, par exemple avec le terme ",? [A-Z]{2}" de l'alternative : son texte-cible risque le cas échéant d'être reconnu à l'avance par la regex $ville (telle que je la soupçonne d'être conçue) avec ce que ça implique de retours arrière. De plus, le terme ", [A-Z]+" (", [A-Za-z]+" dans sa version d'origine) est quasiment équivalent. En fait, plus j'y réfléchis, et moins je vois quelle logique conduit à avoir ces deux termes dans une alternative qui termine une regex. La virgule optionnelle dans l'expression ",? [A-Z]{2}" est redondante : le cas avec virgule est déjà intégralement traité par l'expression ", [A-Z]+". Donc on peut très bien la transformer en " [A-Z]{2}" sans que ça change quoique ce soit au résultat final. Résultat final qui a de forte chances de comporter des caractères en trop ou au contraire des caractères manquants (enfin, ça dépend de comment sont foutus les fichiers). En tout cas, on a cinq termes de l'alternative commençant par un espace : on pourrait factoriser, ça ne mange pas de pain.

    Une dernière remarque : je sais que ça n'a rien d'incorrect, mais je suis toujours un peu perplexe devant une alternative à terme vide, telle que ce "(at|)" qui débute la regex. J'ai mon Friedl sur les genoux, mais j'ai beau chercher je n'arrive pas à retrouver si ç'a un quelconque intérêt par rapport à "(at)?" (si on ne fait rien de la capture, bien sûr).

Discussions similaires

  1. [RSS] extraction des données d'un flux
    Par toddy_101 dans le forum APIs
    Réponses: 4
    Dernier message: 23/02/2007, 17h28
  2. vc++(6)+extraction des données dans une image(.tif)
    Par spootnic22 dans le forum Visual C++
    Réponses: 1
    Dernier message: 22/11/2006, 16h14
  3. [MySQL] Problème de Charset à l'extraction des données
    Par naoufal01 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 06/11/2006, 13h14
  4. extraction des données dans une table Access
    Par moabomotal dans le forum Access
    Réponses: 2
    Dernier message: 26/05/2006, 11h17

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