En fait c'est simple: quand dans une pattern tu répètes un groupe capturant comme ici avec {1,} (ou * ou+) tu obtiendras toujours le dernier résultat. Car à chaque répétition la capture précédente est écrasée par la nouvelle.
La solution la plus simple consiste à retirer ce dernier quantifier {1,} pour obtenir les résultats avec la method find():
(([a-zA-Z]{2,5})([01][0-9]|2[0-3])([0-5][0-9])[ ]*)
Mais elle a le désavantage de seulement trouver les motifs correspondants sans pour autant vérifier que l'ensemble de la chaîne est conforme.
Visiblement tu utilises java. Tu ne peux pas à la fois vérifier la structure global de ta chaîne, et capturer tous les groupes que ce soit avec la méthode find() ou matches(), du fait que tu as un nombre indéterminé de sous chaînes.
Une solution pourrait être de tester la structure de toute la chaîne par la méthode matches() avec cette pattern:
^(?:[a-zA-Z]{2,5}(?:[01][0-9]|2[0-3])[0-5][0-9](?:[ ]+|$))+$
Puis, dans un deuxième temps, d'effectuer un split de la chaîne sur les espaces (\s+)
Une autre solution consisterai à utiliser la méthode find() avec \G pour vérifier que les résultats sont contigus (les uns à la suite des autres ou au début de la chaîne), puis de comparer l'index du dernier caractère de la dernière capture globale (end()) avec la taille de la chaîne de départ (pour vérifier qu'on est bien arrivé à la fin)
\G([a-zA-Z]{2,5}(?:[01][0-9]|2[0-3])[0-5][0-9])(?:[ ]+|$)
Example:
1 2 3 4 5 6 7 8
| String source = "MDG0030 SEB0025";
List<String> result = new ArrayList<String>();
Pattern p = Pattern.compile("\\G([A-Z]{2,5}(?:[01][0-9]|2[0-3])[0-5][0-9])(?:[ ]+|$)");
Matcher m = p.matcher(source);
while (m.find()) {
result.add(m.group(1));
System.out.println(source.length()+"\t"+m.end()+"\t"+m.group());
} |
Partager