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 :

Comment trouver un bloc avec regex ?


Sujet :

Collection et Stream Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Par défaut Comment trouver un bloc avec regex ?
    Bonjour,

    Tout le monde connait ce genre de prose, je pense :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    toto{
     titi;
     truc
     {
       héo{ oui }
     }
    }
    Comment fait-on, avec une regexp, pour trouver l'un quelconque de ces blocs délimités par { } ?

    Merci.

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Le plus simple serait de passer par de la récursivité : tu recherches le groupe le plus grand, puis les plus petit à l'intérieur de ce dernier.

    Par exemple :
    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
    	public static void main(String[] args) throws Exception {
     
    		String input = "toto{\n"
    				+ " titi;\n"
    				+ " truc\n"
    				+ " {\n"
    				+ " héo{ oui }\n"
    				+ " }\n"
    				+ "}\n";
     
     
    		Pattern p = Pattern.compile("\\{(.*)\\}", Pattern.DOTALL);
    		recursiveSearch(p, input, 1);
    	}
     
    	public static void recursiveSearch(Pattern pattern, String input, int groupIndex) {
    		final Matcher m = pattern.matcher(input);
     
    		while (m.find()) {
    			System.out.println("------------------------------");
    			System.out.println(m.group());
    			recursiveSearch(pattern, m.group(groupIndex), groupIndex);
    		}
    	}

    Mais pour que cela fonctionne il faut que le nombre de { et de } soit strictement égaux, si le fichier peut contenir des commentaires ou autres éléments avec des { } cela pourrait poser problème. Dans ce cas là il serait surement plus simple de passer par un analyseur lexicale...

    a++

  3. #3
    Membre Expert
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Dans ce cas là il serait surement plus simple de passer par un analyseur lexicale...
    Je crois que oui...

    J'avais déjà l'impression que c'était le cas, mais je posais la question au cas que j'avais loupé qqchose dans les regex.

    Merci.

  4. #4
    Membre Expert
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Par défaut
    Je signale à toutes fins utiles que je pense avoir trouvé une solution plus satisfaisante, même si elle ne résiste pas au problème des commentaires ou autres finasseries.

    De plus, je ne suis pas sûr à la réflexion que la proposition d'adiGuba fonctionne ?? En particulier je ne comprends pas l'usage de groupIndex ?

    La solution ci-dessous exploite le OU des regexp, pour parcourir une chaine, en comptant les entrées / sorties de bloc ; lorsque le compteur revient à zéro, c'est qu'il est complet :

    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
    34
    35
    36
    37
    38
    39
      public static void main(String[] args) throws Exception {
     
    /* dans l'input on peut commenter divers niveau pour expérimenter */
    		String input = /*"toto{\n"
    				+*/ " titi;\n"
    				+ " truc\n"
    				+ " {\n"
    				+ " héo{ oui }\n"
    				+ " }\n"
    				+ "}\n";
     
     
    		Pattern p = Pattern.compile("\\{|\\}", Pattern.DOTALL);
        Matcher m = p.matcher(input);
        int imbric = 0;
        int startbloc = 0;
        String bloc = "";
        while (m.find())
        {
          if ("{".equals(m.group()))
          {
            imbric++;
            if (startbloc == 0)
              startbloc = m.start();
          }
          else
          {
            imbric--;
            if (imbric < 0)
              imbric = 0; // on s'en fiche.
            else if (imbric == 0)
            {
              bloc = input.substring(startbloc, m.end());
              break;
            }
          }
        }
        System.out.println("youpi = "+bloc);
    	}
    La grosse faiblesse de cette solution est qu'il y a redondance dans le motif et la détection du début de bloc (\\{|\\} d'un coté, { de l'autre : si jamais le motif de début change, il faut penser à le changer aux deux endroits... comme vous le remarquerez, le motif de fin n'a pas cette ennui.

    Conscient de ce que cette approche est de toutes manières fragile, j'ai cherché quelque chose qui fasse office d'analyseur syntaxique dans la JVM, mais je n'ai rien trouvé de convaincant, et je ne connais pas d'analyseur léger... j'ai peur de m'engager dans des grosses mécaniques...

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

Discussions similaires

  1. comment trouver des fichiers avec leur extension seulement?
    Par casual92 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 16/07/2010, 13h43
  2. comment trouver un fichier avec Access
    Par darkspoilt dans le forum VBA Access
    Réponses: 2
    Dernier message: 17/05/2007, 18h58
  3. Comment extraire une partie d'URL avec REGEX?
    Par STB_Fk dans le forum Langage
    Réponses: 2
    Dernier message: 24/01/2007, 12h59
  4. Réponses: 1
    Dernier message: 31/05/2006, 17h59
  5. Réponses: 2
    Dernier message: 25/05/2006, 11h11

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