Bonjour,
Tout le monde connait ce genre de prose, je pense :
Comment fait-on, avec une regexp, pour trouver l'un quelconque de ces blocs délimités par { } ?Code:
1
2
3
4
5
6
7 toto{ titi; truc { héo{ oui } } }
Merci.
Version imprimable
Bonjour,
Tout le monde connait ce genre de prose, je pense :
Comment fait-on, avec une regexp, pour trouver l'un quelconque de ces blocs délimités par { } ?Code:
1
2
3
4
5
6
7 toto{ titi; truc { héo{ oui } } }
Merci.
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:
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++
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 :
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.Code:
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); }
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...