C'est normal car tu utilises .+ pour décrire le contenu entre les balises ouvrante et fermante. Or les quantificateurs sont gourmands par défaut c'est à dire qu'ils vont prendre la plus grande chaîne possible. Une solution est donc d'utiliser un quantificateur non gourmand qui s'écrit ainsi: .+? (on ajoute juste un point d'interrogation pour inverser la tendance d'un quantificateur. De même, on peut écrire *?, {1,5}? ou encore ??.)
Ces deux tendances induisent deux comportements différents pour le moteur de regex:- le quantificateur gourmand prend tous les caractères possible, mais si la suite de la pattern n'est pas satisfaite, le quantificateur gourmand est forcé de rendre des caractères un à un, jusqu'à ce qu'elle le soit. Ce mécanisme s'appelle le backtracking.
- le quantificateur non-gourmand (ou paresseux) fait le contraire, il prend des caractères un à un tant que la suite de la pattern n'est pas satisfaite. Dés qu'elle l'est, il s'arrête.
Néanmoins, pour le problème qui t'occupe, il y a une approche bien plus performante qui consiste à ne pas se préoccuper du contenu entre les balises, pour se concentrer sur les balises elles-mêmes, soit basiquement:
s = s.replaceAll("(?i)<(/?pre\\b[^&]*)>", "<$1>");
(?i) rend la pattern insensible à la casse.
\b est un word boundary (la limite entre un caractère appartenant à la classe de caractère \w et un caractère n'y appartenant pas ou le début ou la fin de la chaîne)
[^&] n'importe quel caractère qui n'est pas un &.
Partager