Bonjour,
J'arrive peut-être trop tard, mais comme j'aime bien les regex... me voici.
a écrit :
Sur un exemple comme
let text = '!toto120:abc-DEF:tqp34';
let result = text.match(/^(![a-z][-a-z0-9]+)?(:[a-z][-a-z0-9]+)*$/gi);
Je m'attendais à obtenir
[ '!toto120:abc-DEF:tqp34', 'toto120', 'abc-DEF', 'tqp34']
ce qu j'obtiens c'est
[ '!toto120:abc-DEF:tqp34', 'tqp34']
J'ai l'impression que ton code ne correspond pas tout à fait avec le résutlat indiqué.
Normalement, le premier item du tableau résultat contient l'ensemble de ce qui a été matché. Les items suivants contiennent la dernière capture de chaque groupe.
Pour les groupes capturants qui se répètent (avec un quantifieur), comme ton
(:[a-z][-a-z0-9]+)*
seul la dernière capture est retournée, les autres sont perdues. Tu devrais recevoir
':tqp34'
.
En fait ce n'est pas la méthode String.match, qui n'exécute qu'une seule fois le matching, que tu devrais utiliser, car tu ne pourras jamais récupérer un nombre variable d'éléments.
Il faut faire un run multiple de la regex sur l'ensemble de la string pour trouver toutes les occurrences une à une. Dit autrement, un match all. En JavaScript sauf erreur ça se fait avec Regex.exec dans une boucle, ou alors éventuellement en utilisant String.replace un peu différemment.
Je pense à quelque chose de ce genre:
let text = '!toto120:abc-DEF:tqp34';
let result = [];
text.replace(/ [decu][a-zA-Z][-a-zA-Z0-9]*)/g, m => result.push(m[1]));
Quant à vérifier que le ! est au début, il faut le faire séparément.
Autrement dit il te faut une regex pour récupérer les éléments comme celle plus haut, et une autre pour vérifier la validité globale de l'entrée.
if (text.match(/^![a-z][-a-zA-Z0-9]*(?::[a-z][-a-zA-Z0-9]*)*$/)) {
// la chaîne est valide, tu peux séparer les différents éléments
}
Mais cette passe de validation globale de l'entrée ne te permet pas de récupérer les différents éléments en même temps, car tu as un nombre d'éléments non fixe.
A noter que, comme déjà relevé, si chaque élément n'est séparé que par ':' alors tu peux plus simplement utiliser String.split pour les séparer.
Par contre ce n'est pas garanti que les performances soient meilleures, car String.split prend en paramètre une regex (et il convertit une string en regex implicitement si on passe une string en paramètre). C'est un truc à bien vérifier, mais bon, de toute façon, il faut d'abord avoir un code qui marche avant de l'optimiser.