Detection de string dans une ligne

Fermé
Senkai Messages postés 21 Date d'inscription mercredi 31 octobre 2012 Statut Membre Dernière intervention 24 mai 2014 - 17 nov. 2012 à 22:32
Senkai Messages postés 21 Date d'inscription mercredi 31 octobre 2012 Statut Membre Dernière intervention 24 mai 2014 - 18 nov. 2012 à 19:41
Bonjour,

Suite à mon précédent sujet
https://forums.commentcamarche.net/forum/affich-26368563-jtextarea-detection-indentation-automatique

Pour résoudre mon problème, j'ai mis toutes les balises dans un tableau et pour chaque ligne j'ai une fonction incrementation (qui prend une ligne en argument) qui ressemble à ca

for (int i = 0 ; i < tableaulength ; i++){
                  if (ligne.contains(tableau[i])){
                 // Met la balise dans une pile (si elle n y est pas déjà) et incrémente la variable indentation
                  }

            decrementation(ligne)
                     
                  }


}



sachant que decrementation contient ca:

   if(!pile.empty()){
                  String balisefermante = "</" + pile.peek() + ">";
                  if (ligne.contains(balisefermante)){
                     //On retire la balise de la pile et on décrémente indentation
                   }
                      decrementation(ligne);





Ca fonctionne assez bien sauf qu'il y a plusieurs problèmes avec la première fonction.
- Le premier c'est que j'aimerai savoir l'ordre dans lequel apparaissent les strings trouvés dans le texte (avec la pile), alors que là je peux seulement recuperer l'ordre dans lequelles ils apparaissent dans le tableau (si une ligne contient plusieurs balises).
- Le second c'est que la méthode est trop complexe, étant donné qu'on doit reparcourir la ligne à chaque case du tableau, et j'aimerai avoir à le faire qu'une seule fois, si possible.

Bref j'aimerai savoir s'il n y a pas une méthode plus efficace pour faire ce que j'ai décrit.

Merci


1 réponse

KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
18 nov. 2012 à 00:44
Je n'ai pas participé à la première discussion, mais si tu lances une nouvelle discussion peut-être est-elle indépendante, sinon j'irai voir ce que dont vous avez parlé avec Heliotte.

Pour ton premier problème je pense avoir une solution, mais ça risque d'être encore plus lourd, ou alors il faut le faire très astucieusement et là c'est le code qui va devenir compliqué (on ne peux pas tout avoir en même temps)

Déjà, une idée pour le premier problème c'est de construire une expression régulière avec toutes tes balises. Si ton tableau contient {"abc", "def", "ghi"} par exemple, on va construire une expression régulière "abc|def|ghi".
Ce n'est bien sûr qu'une idée car il peut y avoir des cas particuliers à traiter, je te donne le cas général, tu régleras les bugs si y en a :

private String generateRegex()
{
    StringBuilder sb = new StringBuilder(tableau[0]);
    for (int i=1; i<tableau.length; i++)
        sb.append("|").append(tableau[i]);
    return sb.toString();
}

Pour ton code avec l'ajout à la pile dans l'ordre de la ligne ça donnerait ça, on lit la ligne jusqu'à trouver un résultat pour l'expression régulière (une balise), on l'ajoute la pile et on continue la ligne jusqu'à ne plus rien trouver :

String regex = generateRegex();

Scanner sc = new Scanner(ligne);	
String balise;
while ((balise= sc.findInLine(regex)) != null)
{
	System.out.println(balise); // la prochaine balise trouvée
	// Mettre la balise etc.
}
sc.close();

Après je ne comprends pas trop ce que tu veux faire avec ta décrémentation, mais peut-être qu'avec un petit exemple je comprendrais ce que tu cherches à faire.
0
Senkai Messages postés 21 Date d'inscription mercredi 31 octobre 2012 Statut Membre Dernière intervention 24 mai 2014 6
18 nov. 2012 à 18:02
Merci pour la réponse.
Je crois comprendre la première partie. En gros on crée un string contenant toutes les expressions du tableau c'est ça?
Par contre pour la seconde, que fait exactement la méthode findInLine?

Sinon décrementation sert juste à arreter l'indentaion. Par exemple si une ligne contient la balise <html> ,alors on met html dans la pile et on augmente la variable indentation (avec la fonction incrementation) jusqu'a ce qu'on trouve ligne contenant </html>, là on retire html de la pile et on decremente indentation. (avec decrementation).
Mais bon j'ai décidé de plutot les appeler separement plutot que l'une à partir de l'autre.
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
18 nov. 2012 à 18:12
findInLine va renvoyer le premier résultat de l'expression régulière trouvée sur la ligne.

Par exemple si ton tableau contient {"html","body","head"}, l'expression régulière "html|body|head" va être vraie dès qu'on aura trouvé "html" ou "body" ou "head". findInLine va chercher dans le texte qu'on lui fournit le premier terme qui valide l'expression régulière. Si la ligne est "<html><head></head><body></body></html>" alors findInLine va renvoyer "html", puis un deuxième appel de findInLine renverra "head", puis dans l'ordre "head", "body", "body", "html".

Remarque : selon tes besoins, on peut 1) améliorer l'expression régulière 2) optimiser le traitement en recodant la recherche de l'expression régulière (une fois qu'elle sera définitive).
0
Senkai Messages postés 21 Date d'inscription mercredi 31 octobre 2012 Statut Membre Dernière intervention 24 mai 2014 6
18 nov. 2012 à 18:27
donc "|" sert de séparateur pour findInLine?
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
18 nov. 2012 à 19:14
C'est comme cela que l'on construit un "OU" dans les expression régulières (html OU body OU head)
Le détail de la syntaxe des expressions régulières Java est dans la documentation de la classe Pattern https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
0
Senkai Messages postés 21 Date d'inscription mercredi 31 octobre 2012 Statut Membre Dernière intervention 24 mai 2014 6
18 nov. 2012 à 19:41
Merci je vais essayer de me debrouiller. Je reposterai si j'ai un problème
0