regex: matching multiple

regex: matching multiple - Perl - Programmation

Marsh Posté le 31-08-2003 à 19:54:45    

Avec le code suivant:

Code :
  1. print foreach(/(?:([^X]*)X)+/);


et la chaine suivante "abcX123XxyzX", j'estime que je devrait obtenir:
abc
123
xyz
Mais en fait je n'obtient que "xyz". Le sous pattern délimité par des parenthèses simples (i.e [^X]*) devrait être matché plusieurs fois dans mon exemple. Je pense que c'est le cas, mais pour autant j'ai l'impression que le résultat de ces premiers matchs est écrasé.
 
Feature ou bug? :??:


Message édité par schnapsmann le 31-08-2003 à 19:56:25
Reply

Marsh Posté le 31-08-2003 à 19:54:45   

Reply

Marsh Posté le 01-09-2003 à 07:24:58    

Et si tu retires le ?: ?? parce que normalement, il empèche la capture, ce qui expliquerait que ton print ne retourne rien pour les précédents.
 
Mais je ne suis pas un expert en Perl...

Reply

Marsh Posté le 01-09-2003 à 10:37:25    

print foreach(/(.*?)X/g);  

Reply

Marsh Posté le 01-09-2003 à 11:26:35    

Avec /(?:([^X]*)X)+/, le moteur va rechercher la plus grande chaîne correspondant au motif, donc dans ce cas: abcX123XxyzX, c-à-d n'importe quelle séquence ([^X]*)X une fois ou plus (à cause du dernier plus). La chaîne entière sera donc détectée, mais le contenu de $1 sera écrasée pour chaque séquence ([^X]*)X puisqu'elle est incluse dans la parenthèse soumise à +. Donc seule la dernière correspondance de ([^X]*) sera conservée: xyz.
 
Pour avoir ce que tu veux, fais:
 
/([^X]*)X/g
 
Sans oublier le commutateur g pour que la recherche s'effectue jusqu'à plus soif...

Reply

Marsh Posté le 01-09-2003 à 11:28:09    

Chiotte de smileys!!! (Désolé, ça me sâoule d'éditer le post précédent! :D )

Reply

Marsh Posté le 01-09-2003 à 12:59:41    

Okay merci à vous; c'est donc impossible à faire par cette approche.
Mon but était de matcher directement une gros pattern de ce genre:

Code :
  1. delim_debut(?:([^X]*)X)*).*delim_fin


en stockant toutes les captures dans la tableau retourné.
Mais vu que la capture ne marche pas comme je le pensais, je vais procéder en deux phases:
1/ capture de la chaine entre les délimiteurs
2/ split sur le séparateur
 
 

Reply

Marsh Posté le 01-09-2003 à 19:37:55    

Ou alors:

Code :
  1. /(?:^DEBUT)?([^X]*)X(?:FIN$)?/g


avec "DEBUT" et "FIN" comme délimiteurs de début et de fin...
 
 
 
Edit: oubli du $.


Message édité par Toucouch le 01-09-2003 à 19:38:53
Reply

Marsh Posté le 30-12-2008 à 17:26:31    

lol, schnappsmann


---------------
TRIPS RIGHT BUNCH F SHUTTLE TOM AND JERRY RIGHT YELLOW
Reply

Marsh Posté le 03-01-2009 à 15:15:13    

schnapsmann a écrit :

Okay merci à vous; c'est donc impossible à faire par cette approche.
Mon but était de matcher directement une gros pattern de ce genre:

Code :
  1. delim_debut(?:([^X]*)X)*).*delim_fin


en stockant toutes les captures dans la tableau retourné.
Mais vu que la capture ne marche pas comme je le pensais, je vais procéder en deux phases:
1/ capture de la chaine entre les délimiteurs
2/ split sur le séparateur
 
 

Si tu veux juste imprimer l'array des matches, ceci colle:

Code :
  1. s/^DEBUT(.*)XFIN$/$1/; print join "\n", split /X/;


 
Par contre, si tu veux récupérer les matches dans un array pour réutilisation, soit tu fais comme précédemment, en récupérant le résultat du split:

Code :
  1. s/^DEBUT(.*)XFIN$/$1/;
  2. my @matches = split /X/;


soit tu fais directement joujou avec les sous-expressions regulieres pour montrer ton niveau de gurutification perlière:

Code :
  1. my @matches;
  2. m/^DEBUT(?:([^X]*)X(?{push @matches, $^N}))*FIN$/;


 
A+,


Message édité par gilou le 03-01-2009 à 15:16:25

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed