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

Collection et Stream Java Discussion :

[Regex] Expressions régulières: sous groupe


Sujet :

Collection et Stream 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 [Regex] Expressions régulières: sous groupe
    bonjour,
    j'ai le code suivant: (s est une variable string, contenu est une string)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Pattern regex = Pattern.compile("(\\W("+s+")\\W)");
    Matcher match = regex.matcher(contenu);
    boolean b = match.find();
    if (b == true) {
    	String matchFound = match.group();
    	String matchColored ="<font size=\"4\" style bgcolor=\"#33CCFF\">"+matchFound+"</font>";
    	contenu = contenu.replaceAll(matchFound, matchColored);
    }
    ça fonctionne très bien sauf si j'ai une variable s par exemple slt et que dans mon texte, j'ai slt(bonjour). J'obtiens
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Autre erreur : 
    java.util.regex.PatternSyntaxException: Unclosed group near index 5
     slt(
    donc j'ai voulu faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Pattern regex = Pattern.compile("(\\W("+s+")\\W)");
    Matcher match = regex.matcher(contenu);
    boolean b = match.find();
    if (b == true) {
    			String matchFound = match.group(2);
    			String matchColored ="<font size=\"4\" style bgcolor=\"#33CCFF\">"+matchFound+"</font>";
    			contenu = contenu.replaceAll(matchFound, matchColored);
    	}
    et ça marche sauf que maintenant, si j'ai une variable ct et que dans mon texte, j'ai action par exemple, alors ça va me repérer le mot action car il contient ct. or moi, je ne veux que ct. C'est pour ça que j'avais mis les \\W. Donc comment faire
    - pour ne surligner que le mot exact et pas un mot qui en inclus un autre
    - ne pas tenir compte des caractères non mot d'avant et d'après ?
    Merci

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 390
    Points : 432
    Points
    432
    Par défaut
    Dans le deuxieme exemple moi il ne trouve pas action.

  3. #3
    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
    slt,
    en fait qd je dis qu'il trouve action (je me suis peut etre mal exprimée) c'est que les lettres ct de action vont etre surlignées aussi. Or moi je ne veux pas car le seul mot du texte que je veux surligner est ct, et pas les lettres ct inclus dans un autre mot. Si tu fais le code suivant, tu auras les lettres ct de action, surlignées.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    s="ct";
    contenu ="action ct ect";
    Pattern regex = Pattern.compile("(\\W("+s+")\\W)");
    Matcher match = regex.matcher(contenu);
    boolean b = match.find();
    if (b == true) {
             String matchFound = match.group(2);
             String matchColored ="<font size=\"4\" style bgcolor=\"#33CCFF\">"+matchFound+"</font>";
             contenu = contenu.replaceAll(matchFound, matchColored);
             System.out.println("contenu="+contenu);
     }
    zone_texte.setText(contenu);
    avec le println, tu obtiens
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    contenu=a<font size="4" style bgcolor="#33CCFF">ct</font>ion <font size="4" style bgcolor="#33CCFF">ct</font> e<font size="4" style bgcolor="#33CCFF">ct</font>

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 390
    Points : 432
    Points
    432
    Par défaut
    J avais bien compris ce que tu voulais. Mais en fait j'avais fait un autre test qui marchait. Parce qu'en fait dans ton code ce qui pause problème ce n'est pas ton expression régulière mais plutôt le replaceAll.

    C'est d'ailleurs également lui qui t'envoie l'exception du premier cas.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 390
    Points : 432
    Points
    432
    Par défaut
    Voila comment tu peux faire, c un peu plus lourd mais je ne c pas si tu as le choix :

    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
    String contenu = "action ct ect";
        	String s = "ct";
        	Pattern regex = Pattern.compile("(\\W("+s+")\\W)");
        	Matcher match = regex.matcher(contenu);
        	boolean b = match.find();
        	System.out.println(contenu);
     
        	while (b) {
        	         String matchFound = match.group(2);
        	         int i = match.start();
        	         String matchColored ="<font size=\"4\" style bgcolor=\"#33CCFF\">"+matchFound+"</font>";
        	         contenu = contenu.substring(0,i)+
    				 contenu.substring(i).replaceFirst(matchFound, matchColored);
        	         b = match.find();
        	}
     
            System.out.println(contenu);

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 390
    Points : 432
    Points
    432
    Par défaut
    Je suis peut etre aller un peu vite.
    Ce que g fait ne suffit pas, ca marche dans le cas ou il ne le trouve qu'une fois ce qui est un peu trop restrictif je pense.
    Mais ce coup ci ca doit tre bon :

    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
    String contenu = "action ct e ct a";
        	String s = "ct";
        	Pattern regex = Pattern.compile("(\\W("+s+")\\W)");
        	Matcher match = regex.matcher(contenu);
        	System.out.println(contenu);
        	String res = "";
        	int oldMatch=0;
        	int newMatch=0;
        	while (match.find()) {
        	         String matchFound = match.group(2);
        	         newMatch = match.start();
        	         res += contenu.substring(oldMatch,newMatch);
        	         oldMatch = match.end();
        	         res += "<font size=\"4\" style bgcolor=\"#33CCFF\">"+
    				 	contenu.substring(newMatch,oldMatch)+"</font>";
        	}
        	res += contenu.substring(oldMatch,contenu.length());
            System.out.println(res);

  7. #7
    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
    j'ai testé ton code et il fonctionne bien dans l'exemple donné. Le probleme c'est que je n'avais pas tout mis dans le premier message. En fait, ma regex et mon replaceAll sont dans une boucle while. Cette boucle permet d'obtenir la variable s. Donc avec les substrings, j'ai des indexoutofboundsexception car à chaque tour de while, je me retrouve avec un oldmatch qui est plus grand que le new match.
    j'ai donc essayé de réinitialiser les old et new match à 0 à chaque nouveau tour de la boucle while. Mais de toute façon il y a le pb de res car à chaque fois on fait res = res+... donc je me retrouve avec un tres tres grand texte, ou on a plusieurs fois la meme chose. Cette nuit j'ai dormi que 3 heures, c'est peut etre pour ça que je vois pas comment faire Je mets qd meme le 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
     
    while(rs.next()){
    oldMatch=0;
    newMatch=0;
    String s = rs.getString("name");
    Pattern regex = Pattern.compile("(\\W("+s+")\\W)");
    Matcher match = regex.matcher(contenu);
    while (match.find()) {
          String matchFound = match.group(2);
          newMatch = match.start();
          res += contenu.substring(oldMatch,newMatch);
          oldMatch = match.end();
          res += "<font size=\"4\" style bgcolor=\"#33CCFF\">"+       contenu.substring(newMatch,oldMatch)+"</font>";
    }
    }		
    res += contenu.substring(oldMatch,contenu.length());
    zone_texte.setText(res);
    }

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 390
    Points : 432
    Points
    432
    Par défaut
    Si g bien compris tu as plusieurs recherche successive à faire dans le même corps de texte.
    Dans ce cas à la fain de chaque boucle while tu ajoute
    c tout, ce qui donne:
    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
    while(rs.next()){
    res = "";
    oldMatch=0;
    newMatch=0;
    String s = rs.getString("name");
    Pattern regex = Pattern.compile("(\\W("+s+")\\W)");
    Matcher match = regex.matcher(contenu);
    while (match.find()) {
          String matchFound = match.group(2);
          newMatch = match.start();
          res += contenu.substring(oldMatch,newMatch);
          oldMatch = match.end();
          res += "<font size=\"4\" style bgcolor=\"#33CCFF\">"+       contenu.substring(newMatch,oldMatch)+"</font>";
    }
    }      
    res += contenu.substring(oldMatch,contenu.length());
    contenu = res;
    zone_texte.setText(res);
    }
    Mais ca risque d'etre dangereux, parce que les recherches suivantes vont se faire sur un coprs de texte déjà modifié. Pour éviter cela tu pourrais mettre toutes tes recherche dans un seule expresion régulière en liant les mot avec un "|", à savoir faire un disjonction de tous les mots :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    \w(mot1)\w|\w(mot2)\w ...
    ca se fait facilement en faisant une simple boucle sur ton rs.next() en mettant les rs.getString("name") bout à bout.

  9. #9
    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
    slt,
    dsl g pas pu répondre + tot.
    j'ai essayé de faire toutes les recherches en une. ça fonctionne partiellement. J'obtiens bien tous les mots que je voulais surligner et je n'ai plus le pb des parentheses (qd j'avais "slt(" et que je cherchais "slt"). Mais apparemment, il y a une analyse du texte caracteres par caracteres. Qd je fais un println des old match et new match, ça affiche:
    old=0, new =0,
    old=0, new=1,
    old=1, new=2,
    old=2, new=3...
    et si je fais un println de res, j'ai:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ...<font size="4" style bgcolor="#33CCFF"></font> <font size="4" style bgcolor="#33CCFF"></font> <font size="4" style bgcolor="#33CCFF"></font> <font size="4" style bgcolor="#33CCFF"></font> <font size="4" style bgcolor="#33CCFF"></font>b<font size="4" style bgcolor="#33CCFF"></font>e<font size="4" style bgcolor="#33CCFF"></font>e<font size="4" style bgcolor="#33CCFF"></font>n<font size="4" style bgcolor="#33CCFF"></font>...
    je voulais aussi que soient surlignés seulement les mots de la base, sans les caracteres non mots (\W) qui précèdent et qui suivent. Donc avt ds mon code, je mettais match.group(2). Mais maintenant que j'ai une expression qui regroupe tout, je ne sais pas comment faire. Quels chiffres mettre car il y a plusieurs groupes à récupérer? et je ne sais pas lesquels. Je suppose que ce sera un multiple de i. Donc pour savoir ceux qui m'interessent, j'ai testé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    while (match.find()) {
    for(int i=1; i<match.groupCount()+1;i++){
     if(match.group(i)!=null){
    	System.out.println("i= "+i+" match= "+match.group(i));
     }
    }
    mais ça ne rentre jamais dans le if car tous les match.group st null et je ne sais pas pourquoi.

    voici le code en entier:
    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
    if (cb == e.getItem()){
    ResultSet rs = statement.executeQuery("select * from ...");
    		while(rs.next()){
    			String s = rs.getString("name");
    			tout = tout +"(\\W"+"("+ s +")"+"\\W)"+"|";
    		}
    		Pattern regex = Pattern.compile(tout);
    		Matcher match = regex.matcher(contenu);
    		while (match.find()) {
    			String matchFound = match.group(); //je ne sais pas quel nb mettre
    			newMatch = match.start();
    			System.out.println("old = "+oldMatch);
    			System.out.println("new = "+newMatch);
    			res += contenu.substring(oldMatch,newMatch);
    			oldMatch = match.end();
    			res += "<font size=\"4\" style bgcolor=\"#33CCFF\">"+contenu.substring(newMatch,oldMatch)+"</font>";
    		}
    		res += contenu.substring(oldMatch,contenu.length());
    		contenu = res;
    		zone_texte.setText(res);
    }
    il y a aussi ds le text pane: html> head> /head> body> qui apparaissent au début du texte et /body> /html> qui apparaissent à la fin du texte car les balises ne st pas bien ouvertes ou fermées et je suppose que ça a un rapport avec le fait que il y ait des font caracteres par caractères.

    voila je sais pas si je suis tres clair (hesite pas à le dire
    et encore merci pour toute ton aide depuis le début.

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 390
    Points : 432
    Points
    432
    Par défaut
    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
    if (cb == e.getItem()){
    ResultSet rs = statement.executeQuery("select * from ...");
     
          String tout = "(\\W(";
          while(rs.next()){
             String s = rs.getString("name");
             if (rs.isLast())
                   tout += "s|";
             else
                   tout += "s";
          }
          tout += ")\\W)";
     
          Pattern regex = Pattern.compile(tout);
          Matcher match = regex.matcher(contenu);
          while (match.find()) {
             String matchFound = match.group(); //je ne sais pas quel nb mettre
             newMatch = match.start()+1;
             System.out.println("old = "+oldMatch);
             System.out.println("new = "+newMatch);
             res += contenu.substring(oldMatch,newMatch);
             oldMatch = match.end()-1;
             res += "<font size=\"4\" style bgcolor=\"#33CCFF\">"+contenu.substring(newMatch,oldMatch)+"</font>";
          }
          res += contenu.substring(oldMatch,contenu.length());
          contenu = res;
          zone_texte.setText(res);
    }
    G modifié un peu l expression régulière pour n'avoir qu'un sous-groupe parce que ta boucle "for" risque d'etre assez lourde, et g supprimer les caractère autour du mot trouvé.
    Par contre dans mes tests il ne fait pas du caractère par caractère, alors ca vient peut etre de ton resultset qui contient un espace ou qqchose comme ca (imprime l'expression pour le savoir).
    Voila mon test :
    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
    int newMatch = 0;
        	int oldMatch = 0;
        	String res = "";
        	String contenu = "-ct--af--ct(bonjout)   ct     af     vbg";
        	Pattern regex = Pattern.compile("(\\W(ct|af)\\W)");
            Matcher match = regex.matcher(contenu);
            while (match.find()) {
               String matchFound = match.group(); //je ne sais pas quel nb mettre
               newMatch = match.start()+1;
               System.out.println("old = "+oldMatch);
               System.out.println("new = "+newMatch);
               res += contenu.substring(oldMatch,newMatch);
               oldMatch = match.end()-1;
               res += "<font size=\"4\" style bgcolor=\"#33CCFF\">"+contenu.substring(newMatch,oldMatch)+"</font>";
            }
            res += contenu.substring(oldMatch,contenu.length());
            contenu = res;
            System.out.println(res);

  11. #11
    Membre confirmé Avatar de billynirvana
    Homme Profil pro
    Architecte technique
    Inscrit en
    Décembre 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2004
    Messages : 472
    Points : 552
    Points
    552
    Par défaut
    C'est un alignement de chaine de caractères que tu veux faire???


    style:

    ALPHONSE
    TELEPHONE


    dis moi car j'ai déjà fait cet algorithme, et il marche

  12. #12
    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

    bah je sais plus koi dire, à part
    encore une fois, tu as résolu mon problème
    t'es un boss en java et notamment sur les regex
    alors sincèrement merci pour le temps que tu passes pour m'aider.
    a bientot (car j'en doute pas une seconde, je vais bientot bloquer sur un autre probleme )
    bonne apres midi

  13. #13
    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
    slt billynirvana, je viens de voir ta réponse. non, ce n'était pas un alignement que je faisais, mais merci d'avoir proposé ton aide. barbu0055 a trouvé une solution.

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

Discussions similaires

  1. [REGEX] expression régulière qui match tout les nombres sauf un
    Par neuromencien dans le forum Collection et Stream
    Réponses: 11
    Dernier message: 28/05/2008, 08h21
  2. Expressions régulières et groupes capturants
    Par ®om dans le forum Langage
    Réponses: 1
    Dernier message: 09/01/2008, 15h37
  3. [Débutant][Regex] Expression régulière adaptée
    Par hm1ch dans le forum Windows Forms
    Réponses: 1
    Dernier message: 15/06/2007, 21h50
  4. [REGEX]Expression régulière
    Par tomca dans le forum Langage
    Réponses: 2
    Dernier message: 10/10/2005, 11h01
  5. [RegEx]Expression régulière
    Par Sniper37 dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 07/06/2005, 11h18

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