Ce n'est jamais à faire.Sinon pour ton code, ma suggestion est effectivement qu'à toute fermeture rencontrée, tu prends la dernière ouverture antérieure non-traitée encore possible.
Voilà ma suggestion dans ton else :
foreach (candidat in candidats) {
if (candidat.est_compatible_avec(balise)) {
candidat.ajoute(balise);
if (balise.est_fermante) {
if (balise.index < candidat.index) {
candidat_compatible = candidat;
/*
* Je ne suis pas sûr de ton langage et comment l'on récupère les
* index. En somme, le candidat compatible (donc ouvrant) doit être
* la dernière balise ouvrante compatible entre le début du post et
* la balise fermante actuellement traitée.
*/
} else {
// On a fini les candidats compatibles jusqu'à la balise, pas besoin
// de vérifier les suivants
break;
}
}
}
}
if (isset(candidat_compatible)) {
// Maintenant qu'on a le candidat compatible, on peut traiter la séquence
candidats.supprime(candidat_compatible);
sequences.ajoute(candidat_compatible);
annuler_balises_superposees(candidats, candidat_compatible);
unset(candidat_compatible); // On supprime la variable pour les prochaines séquences
}