Aide - Recherche - Membres - Calendrier
Version complète : Regex : Répétition d'un même caractères
La Communauté TitaXium > Service Communication > Espace Developpement
Nokilling
Salut tout le monde smile.gif
Voila, c'est encore moi avec mes problèmes de regex ^^
Cette fois ci, j'ai un problème pour la fin de recherche wacko.gif

Donc j'ai une regex de ce genre :
Code
{func=(.*?):(.*?)}


Mais le problème, c'est que si j'ai un truc de ce genre :
Code
{func=test:{func=test:toto}}


Le problème, c'est que lors du premier passage, il ne récupère que ces deux bouts :
Citation
test


Et
Citation
{func=test:toto


Alors que moi, je voudrais qu'il me récupère en plus le } de fin. Mais le problème c'est qu'il peut y avoir théoriquement X fois } à la fin, si l'on imbrique plusieurs fois la chaine.
Donc je ne vois pas comment faire pour lui dire de toujours prendre ça, et de ne prendre en compte que le } comme délimiteur de fin.

Merci d'avance et bonne vacances smile.gif
K20
Alors si j'ai bien compris tu veux récupérer le nom de la fonction (ici test) et les arguments du style {func=test:toto} c'est ça ?
Nokilling
Oui exactement ça smile.gif
Et je ne comprend pas comment lui dire de le récupérer, car avec le $, ça fait que ça doit être la fin de la chaine de caractères, et ce n'est pas toujours le cas :s ( ça l'est même que très très rarement :s)
K20
Les { } sont des métacaractères, on s'en sert pour marquer une répétition de caractères, essaye ça :
Code
\{func=(.*):(.*)\}$


De plus je vois pas trop l'intérêt du "?" vu que * indique déjà 0, 1 ou plusieurs fois la répétition de n'importe quel caractère.

Je suis pas certain de ma regexp, je l'ai pas testé ...
Nokilling
La raison du .*?, c'est que je l'avais trouvé sur un site anglais pour récupérer le contenu entre deux balises html, donc dans mon cas j'ai repris cette exemple, car si je prend la tienne, ce qu'il récupère en premier lieu c'est :
Citation
bbcode:{func=test


Alors que je voudrais qu'il ne récupère que bbcode smile.gif
Et sinon, l'autre problème, c'est qu'avec le $, ça doit être à la fin de la chaine, alors que c'est pratiquement jamais le cas :'(

Ps : Voici l'article en question : http://www.regular-expressions.info/examples.html
K20
Je finis un truc en C++ et je regarde ça plus en profondeur
Donne moi plusieurs exemples possibles pour que je teste wink.gif
Nokilling
Ok, ba voila l'exemple que j'utilise pour mes test :
Citation
Ma fonction spéciale = {func=bbcode:{func=test:toto}} Toutinet
Toto est là


Et donc, en faites, la regex doit récupérer tout l'ensemble en gras smile.gif et ne pas s'arréter dès qu'elle trouve le premier }

Merci pour ton aide smile.gif

Edit : Voila, j'ai un tout petit peut avancé tongue.gif

Donc voila, avec cette regex : "|{func=(.*?)sad.gif.*?)\}+|", je récupère tout ce qui est en gras, mais le problème, c'et que pour le deuxième élément il me récupère que :
Citation
{func=test:toto


Il me manque le } de fin, car si je me trompe pas, le quantificateur +, c'est pour au moins un voir plus non ? Et donc vu qu'il y en a deux, il le prend alors en compte :s
K20
Ha mais ça change tout comme ça tongue.gif
Je pensais que tu voulais que bbcode et test:toto moi tongue.gif

Tu utilises quoi comme fonction php pour faire ça, file moi ton morceau de code
Nokilling
Ba j'utilise pour le moment ça :
Code
$content = preg_replace_callback(
            "|{func=(.*?):(.*?)\}+|",
            array(get_class($this), 'func'),
            $content);


Donc pour le moment, je récupère tout, et j'ai trouvé une solution pas trop jolie pour qu'il me récupère bien la suite smile.gif

Code
        $function = $match[1];
        $param = explode(',',$match[2]);
        foreach($param as $key=>$value){
            if(ereg("^{func=",$value)){
                $value.="}";
            }
            $param[$key] = $this->parse($value);
        }
        return call_user_func_array($function,$param);


Mais au finale ça marche ^^
Donc si on peut éviter de faire un deuxième test en utilisant les regex ^^
K20
Ba après c'est surtout niveau performance, utiliser direct une regexp sera plus rapide que ton 2e code, mais si ton 2e fonctionne et que sur tes tests ça prend pas trop longtemps utilise la 2e méthode wink.gif
Nokilling
Citation (K20 @ 23 Aug 2008, 17:28) *
Ba après c'est surtout niveau performance, utiliser direct une regexp sera plus rapide que ton 2e code, mais si ton 2e fonctionne et que sur tes tests ça prend pas trop longtemps utilise la 2e méthode wink.gif


En faites ils ne fonctionnent pas parfaitement ^^
Car le problème, c'est qui ne prenait pas en compte les bons paramêtres pour les bonnes fonctions ^^
Donc maintenant je me retrouve avec un truc comme ça :
Code
        echo"<pre>".print_r($match,true)."</pre><hr />";
        $function = $match[1];
        $param = $this->parse($match[2]);
        $param = explode(',',$param);
        echo"<pre>".print_r($param,true)."</pre><hr />";
        return call_user_func_array($function,$param);


Sauf que maintenant, je ne vois pas comment faire pour rajouter le } de fin, car il se peut que la chaine ne soit pas en dernière position wacko.gif

Et aussi, si je fais un truc du genre :
Citation
{func=test:{func=substr:{var.titre},0,200},Tutu}


Il ne prend pas en compte le Tutu}, alors qu'il devrait le prendre :'(


Edit : Enfin !! smile.gif, j'ai enfin réussi, à force d'essayer un peut toute les options des regex, je suis tombé sur le U qui marche très bien (c'est pour l'option gourmande du ? smile.gif ) ^^

Donc avec la regex principale :
Code
|{func=(.*):(.*?)}|U


Pour le texte suivant :
Citation
Ma fonction spéciale = {func=test:{func=substr:{var.titre},0,200},Tutu}


J'ai comme résultat ça :
Citation
Array
(
[0] => {func=test:{func=substr:titi,0,200},Tutu}
[1] => test
[2] => {func=substr:titi,0,200},Tutu
)



[Edit2] Voila, ne trouvant pas de solution, j'ai fait un truc mais vraiment trop pas optimiser, mais il marche :s
Donc voici le code, qui pour ma phrase de départ :

Citation
{func=substr:titi,0,2},Tutu,{func=substr:toto wink.gif,0,2}


Et je voudrais avoir comme résultat un truc du genre :
Citation
Array
(
[1] => {func=substr:titi,0,2}
[2] => Tutu
[3] => {func=substr:toto wink.gif,0,2}
)

Me retourne tout ce que je voulais :
Code
        $function = $match[1];
        $param = explode(',', $match[2]); // On explode selon les ,
        $func = false; // Par défault on n'est pas dans une fonction
        $key = 0; // On initialise à 0
        foreach($param as $value){ // On liste tout nos paramêtres
            if(ereg('{',$value)){ //Si on est en début de fonction, on incrémente $key, et on indique que l'on est dans une fonction
                $func = true;
                $key++;
            }
            if($func){
                if(strlen($tmp[$key]) != 0){ //Vérifie pour éviter de mettre une virgule devant le {func
                    $tmp[$key].= ',';
                }
                $tmp[$key].= $value;
            }else{ //Si on n'est pas dans une fonction, on ajoute directement la value dans le tableau
                $tmp[$key] = $value;
            }
            if(ereg('}',$value)){
                $func = false;
                $key++;
            }
        }


Donc voila, si quelqu'un à des idées pour les optimisations, car là j'ai fais ça sans réfléchir, juste pour que ça marche ^^
Ceci est une version "bas débit" de notre forum. Pour voir la version complète avec plus d'informations, la mise en page et les images, veuillez cliquer ici.
Invision Power Board © 2001-2010 Invision Power Services, Inc.