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 Java Discussion :

[debutant]expressions régulières


Sujet :

Langage Java

  1. #1
    Membre actif
    Inscrit en
    Janvier 2005
    Messages
    629
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 629
    Points : 203
    Points
    203
    Par défaut [debutant]expressions régulières
    Bonjour,
    j'ai un texte contenant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ...<exemple>...</exemple>...<exemple>...</exemple>...
    Mon but est de récupérer :
    <exemple>...</exemple>
    <exemple>...</exemple>
    J'utilise des expressions régulières:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Pattern regex = Pattern.compile("<exemple>(.)*</exemple>");
    j'ai mis (.)* car il peut y avoir un nombre indéfini de caractères entre les balises.
    Mais je récupère:
    <exemple>...</exemple>...<exemple>...</exemple>
    car ça s'arrete à la dernière occurence de </exemple>
    Comment faire pour que ça s'arrete à la premiere occurence de </exemple> afin que ça me récupère séparément les 2 exemples ?

    Merci

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    304
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 304
    Points : 348
    Points
    348
    Par défaut
    Pourquoi n'utilises-tu pas les fonctions de la classeString, par exemple, indexOf() et substring()
    --Miss Gaëlle--

  3. #3
    Membre habitué Avatar de Kenji
    Inscrit en
    Janvier 2005
    Messages
    129
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Janvier 2005
    Messages : 129
    Points : 143
    Points
    143
    Par défaut
    Les () sont la pour cibler que tu captures,la tes () englobent le tout c est donc normal que tu recuperes tout.
    Dans ton cas ce serait plutot:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (<exemple>.*</exemple>).*(<exemple>.*</exemple>)
    Sinon la partie regex dans la JavaDoc est tres bien faite si tu cherches a matcher des expressions régulières précises.

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    154
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 154
    Points : 143
    Points
    143
    Par défaut
    essaie ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <exemple>(.+?)</exemple>
    J'avoue que je ne sais pas trop comment ca marche mais c'est une histoire d'operateur reluctant : c'a en prend le moins possible (il s'arrête dès qu'il trouve un match alors que ce que tu as fait essaie de faire le plus gros match possible).
    J'ai repris un exemple sur le net et je me suis fait un exemple.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    		String content = "to b ti c to ta ti";
    		String pattern = "to(.*?)ti";
    		Pattern p = Pattern.compile(pattern);
    		Matcher matcher = p.matcher(content);
    		System.out.println();
    		while(matcher.find()){
    			System.out.println(matcher.group(1));
    		}
    et le résultat est :
    Bonne chance, Bonne journée, bonne année bonne santée et etc ...
    Youpi la vie est belle ! Et vive la fraicheur

  5. #5
    Nouveau membre du Club

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 48
    Points : 31
    Points
    31
    Par défaut
    losrque je travaille avec du texte moi j utilise la classe StreamTokenizer.
    look la javadoc de StreamTokenizer

    l algo est assez simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    tant que le token n est pas la balise <exemple> faire
      next token
    fin tant que
    //tu recois le premier <exemple>
    tant que le token n est pas la balise </exemple>
      concatener le token avec le String precedent
    Fin tant que
     
    et tu repetes cet algo tant que tu narrive aps a END OF FILE

  6. #6
    Membre actif
    Inscrit en
    Janvier 2005
    Messages
    629
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 629
    Points : 203
    Points
    203
    Par défaut
    Bonjour,
    Tout d'abord merci à tous d'avoir répondu. Alors j'ai testé les différentes possibilités mais j'ai quelques problèmes.

    En effet, mon texte se présente de la façon suivante (a mon 1er message, j'avais un peu simplifié):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ...<joueur> joueur1 </joueur> a pour fonction <fonction> fonction1 </fonction> et le <joueur> joueur2 </joueur> a pour role <role> role2  </role>...
    Je veux récupérer DANS L'ORDRE (et c'est entre autre ça mon pb):
    joueur1
    fonction1
    joueur2
    role2
    Avec la technique de Tiaps, ça marche très bien mais je ne les récupères pas dans l'ordre à cause de mes boucles while qui se font successivement. Je récupère: joueur1, joueur2, fonction1, role2
    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
    17
    18
    19
    20
    21
    22
     
    Pattern regex_joueur = Pattern.compile("<joueur>(.*?)</joueur>");
    Pattern regex_fonction = Pattern.compile("<fonction>(.*?)</fonction>");
    Pattern regex_role = Pattern.compile("<role>(.*?)</role>");
    Matcher match_joueur = regex_joueur.matcher(contenu);
    Matcher match_fonction = regex_fonction.matcher(contenu);
    Matcher match_role = regex_role.matcher(contenu);
    //contenu est une String et correspond au texte
    while(match_joueur.find()){
    	String matchFound = match_joueur.group(1);
    	System.out.println(matchFound);
    }
     
    while(match_fonction.find()){
    	String matchFound = match_fonction.group(1);
    	System.out.println(matchFound);
    }
     
    while(match_role.find()){
    	String matchFound = match_role.group(1);
    	System.out.println(matchFound);
    }
    Donc avec cette technique, je ne sais pas comment arranger les boucles while pour que je récupère les données dans l'ordre ou elles apparaissent dans le texte et non regroupées par type.

    J'ai alors testé avec les stream tokenizer que je ne maitrise pas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    st = new StreamTokenizer (new BufferedReader (new StringReader (contenu))) ;
    //contenu est une String
    String debut = "<joueur>";
    String fin = "</joueur>";
    String phrase ="";
    while(st.ttype != StreamTokenizer.TT_EOF){ 
            while (st.sval != debut)
    	     st.nextToken();        
    	while (st.sval != fin){
    	     st.nextToken();
    	     phrase = phrase + st.sval;
    	}
    }
    ici, ça tourne non stop dans la boucle while (st.sval != debut ). Par ailleurs, une fois que ce pb sera résolu, je pense que j'aurai toujours le probleme d'obtenir mes données dans l'ordre d'apparition car il y aura toujours le pb des boucles while.

    Je n'ai pas fait la methode de kenji car effectivement ça aurait fonctionné pour mon premier message mais je l'avais simplifié. L'ordre et le nombre des balises ne sont pas connus à l'avance.

    J'ai essayé la methode de miss gaelle: je récupere bien les parties mais j'ai le meme probleme , je ne sais pas comment faire avec les boucles while pour récupérer les données dans l'ordre.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int index_debut_joueur = contenu.indexOf("<joueur>");
    int index_fin_joueur = contenu.indexOf("</joueur>");
    int index_debut_fonction = contenu.indexOf("<fonction>");
    int index_fin_fonction= contenu.indexOf("</fonction>");
    int index_debut_role = contenu.indexOf("<role>");
    int index_fin_role= contenu.indexOf("</role>");
    String phrase_joueur = contenu.substring(index_debut_joueur, index_fin_joueur);
    String phrase_fonction= contenu.substring(index_debut_fonction, index_fin_fonction);
    String phrase_role = contenu.substring(index_debut_role , index_fin_role );
    Vous l'aures compris, mon pb, ce st les boucles while, je ne sais pas comment les arranger entre elles, pour récupérer les données ds l'ordre d'apparition dans le texte. Si vous voyez comment faire avec l'une ou l'autre des solutions, n'hesitez pas!
    Merci

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    154
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 154
    Points : 143
    Points
    143
    Par défaut
    Tu peux peut être créé une expression régulière qui gére le tout.

    Sinon, tu peux peut être stocker l'emplacement où ont été trouvé les match puis les triés à la fin??? (tu dois avoir le début du match avec la méthode start() de Matcher)
    Bonne chance, Bonne journée, bonne année bonne santée et etc ...
    Youpi la vie est belle ! Et vive la fraicheur

  8. #8
    Nouveau membre du Club

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 48
    Points : 31
    Points
    31
    Par défaut
    tu t es goure avec les streamtoken

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    st = new StreamTokenizer (new BufferedReader (new StringReader (contenu))) ; 
    //contenu est une String 
    String debut = "<joueur>"; 
    String fin = "</joueur>"; 
    String phrase ="";
    st.nextToken(); 
    while(st.ttype != StreamTokenizer.TT_EOF){ 
            while ((st.ttype==StreamTokenizer.TT_WORD)&& ((st.sval).compareTo(debut)!=0)) 
            st.nextToken();        
       while ((st.ttype==StreamTokenizer.TT_WORD)&& ((st.sval).compareTo(fin)!=0)){
            st.nextToken(); 
            phrase = phrase + st.sval; 
       } 
    }
    je l ai rapidement corrige mais pour comparer des string tu le fais avec compareTo()
    normalement cette methode marche correctement

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    154
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 154
    Points : 143
    Points
    143
    Par défaut
    Voilà si tu veux j'ai réussi à le faire. Si tu as d'autre balise, à rajouter, je te conseillerais de faire une méthode qui construit le pattern.
    La boucle for commence à 1 pour ne pas prendre en compte le groupe 0 qui renverrai <balise>contenu</balise>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    		String content = "...<joueur> joueur1 </joueur> a pour fonction <fonction> fonction1 </fonction> et le <joueur> joueur2 </joueur> a pour role <role> role2  </role>... ";
    		String pattern = "<fonction>(.*?)</fonction>|<joueur>(.*?)</joueur>|<role>(.*?)</role>";
    		Pattern p = Pattern.compile(pattern);
    		Matcher matcher = p.matcher(content);
    		System.out.println();
    		while(matcher.find()){
    			for(int i=1; i<matcher.groupCount()+1;i++){
    				if(matcher.group(i)!=null){
    					System.out.println(matcher.group(i));
    				}else{
    //					System.out.println(i+" is null");
    				}
    			}
    		}
    Bonne chance, Bonne journée, bonne année bonne santée et etc ...
    Youpi la vie est belle ! Et vive la fraicheur

  10. #10
    Membre actif
    Inscrit en
    Janvier 2005
    Messages
    629
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 629
    Points : 203
    Points
    203
    Par défaut
    Je venais suite à ton message de 13h, de faire une expression régulière qui combine le tout. Elle ressemble en gros(!) à la tienne, avec les OR.
    Donc merci à toi et à tous les autres dont v1nc3kro (g testé aussi ce que tu m'avais corrigé).
    Merci à tous. C'est très sympa de votre part.
    a bientot.

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 20/09/2006, 13h16
  2. [debutant] Expression régulière : retour ligne
    Par absolut75 dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 12/07/2006, 16h48
  3. [debutant]expressions régulières
    Par debdev dans le forum Langage
    Réponses: 5
    Dernier message: 16/06/2005, 10h47
  4. [Debutant]indexOf et expressions régulières
    Par The Wretched dans le forum Langage
    Réponses: 2
    Dernier message: 14/04/2005, 09h21
  5. [Debutant(e)]Expressions régulières d'un login?
    Par martimacfly dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 27/08/2004, 16h28

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