Vérification et correction regex svp

ViPHP
ViPHP | 2287 Messages

11 févr. 2012, 00:25

J'ai pas vraiment commencer, mais le compteur risque d'interdire les citations différentes non?
On parcourt simplement le post, caractère par caractère, avant le passage par ta fonction zcode, et on cherche par comparaison de chaîne les ouvertures et fermeture de citation qu'il contient.

Un compteur simple calculerait +1 pour chaque ouverture de citation rencontrée, et à la fin on calcule le total obtenu. Et dans ce cas, on aurait un souci car que le post contienne 4 citations à un seul niveau, ou 1 citation à 4 niveaux, on obtiendrait dans les deux cas un total de 4 en fin de parcours.

Si on compte les fermetures (-1 par fermeture), c'est presque pareil. Sauf que le compteur devrait retomber à 0 à la fin, et le total devient donc une information inutile. Il ne faut plus lire le total à la fin mais observer la valeur du compteur en cours de route :) Et dans ce cas, pour un post qui contient 4 citations simples, on aurait le parcours suivant :

Code : Tout sélectionner

$compteur = 0 <citation> +1 $compteur = 1 </citation> -1 $compteur = 0 <citation> +1 $compteur = 1 </citation> -1 $compteur = 0 <citation> +1 $compteur = 1 </citation> -1 $compteur = 0 <citation> +1 $compteur = 1 </citation> -1 $compteur = 0
Donc à tout moment on a $compteur qui ne dépasse pas 1. Tout va bien :)

En revanche si le post contient une citation à 4 niveaux :

Code : Tout sélectionner

$compteur = 0 <citation> +1 $compteur = 1 <citation> +1 $compteur = 2 <citation> +1 $compteur = 3 <citation> +1 $compteur = 4 </citation> -1 $compteur = 3 </citation> -1 $compteur = 2 </citation> -1 $compteur = 1 </citation> -1 $compteur = 0
On a franchi le palier (3), on peut donc sortir en erreur dès que la conditon est rencontrée.

Une simple boucle (while, for), quelques if() et la fonction stpros ( http://fr.php.net/manual/fr/function.strpos.php ) feraient bien ce job :)

Tout ça peut aussi se faire en regexp (ce serait même plus court, y'a juste la regexp à faire en fait, et tu as déjà tout le matériel nécessaire pour ça sous les yeux). C'est vraiment comme tu le sens :D
if(!@work()){ Nespresso(); } else { what(); }
______________________________

Eléphant du PHP | 418 Messages

11 févr. 2012, 01:59

Merci à toi

Je m'y attèle demain si tout va bien

Cordialement

Eléphant du PHP | 418 Messages

12 févr. 2012, 21:28

j'ai tenter pas mal de trucs, mais j'arrive pas à compter le nombre d'entrées.

J'ai fait une regex qui prend dans ses paramettres: " <citation>{1,3} ", dans l'idée (j'ai perdu la regex complète, je croyais l'avoir mise de coté mais je la retrouve pas), mais j'ai pas réussit.

Sans me donner la réponse, pourrais tu me montrer à quoi ça dois ressembler au final?? stp

Merci de ton aide

Cordialement

ViPHP
ViPHP | 2287 Messages

12 févr. 2012, 22:18

j'ai tenter pas mal de trucs, mais j'arrive pas à compter le nombre d'entrées.

J'ai fait une regex qui prend dans ses paramettres: " <citation>{1,3} ", dans l'idée (j'ai perdu la regex complète, je croyais l'avoir mise de coté mais je la retrouve pas), mais j'ai pas réussit.

Sans me donner la réponse, pourrais tu me montrer à quoi ça dois ressembler au final?? stp

Merci de ton aide

Cordialement
Il suffit de se demander à quoi ressemblerait un post qui ne convient pas (c'est à dire présentant une citation sur quatre niveaux), si on le lit "normalement" :

Code : Tout sélectionner

***<citation>***<citation>***<citation>***<citation>***</citation>***</citation>***</citation>***</citation>***
( Il faut imaginer que chaque *** représente un bout de texte qui est optionnel, le reste étant les parties qui nous intéressent ).
Pour le cas particulier de cette regexp on peut ignorer les bouts de texte du début et de la fin, ce qui donne :

Code : Tout sélectionner

<citation>***<citation>***<citation>***<citation>***</citation>***</citation>***</citation>***</citation>
On va maintenant traduire cela en langage regexp. Comme nos *** peuvent contenir des retours à la ligne, on va utiliser le modifieur s. On va aussi utiliser le modifieur U ici (pour gérer les cas les plus compliqués). Je t'ai choisi un @ comme délimiteur ici puisque le / est déjà utilisé dans le motif (choisir un bon délimiteur évite de mettre des \ partout).

Code : Tout sélectionner

@<citation>(.*)<citation>(.*)<citation>(.*)<citation>(.*)</citation>(.*)</citation>(.*)</citation>(.*)</citation>@sU
Attention, ce n'est pas testé, mais tu as maintenant une idée pour continuer.

@+
if(!@work()){ Nespresso(); } else { what(); }
______________________________

Eléphant du PHP | 418 Messages

12 févr. 2012, 22:54

Super c'est simpa.

Je vais tester ça avec une condition du style if(!preg_match){ok}

Merci, je te tiens informé

Cordialement

Eléphant du PHP | 418 Messages

12 févr. 2012, 23:11

ça fonctionne

Maintenant pour utiliser la même regex qu'il y est un nom=? ou pas, comment dois je m'y prendre?

j'ai tester cette regex, ça prend que les nom=?, pas les simples citations
if(preg_match('@<citation (.*)>(.*)<citation (.*)>(.*)<citation (.*)>(.*)<citation (.*)>(.*)</citation>(.*)</citation>(.*)</citation>(.*)</citation>@sU',$message))
Merci de ton aide

Cordialement

ViPHP
ViPHP | 2287 Messages

12 févr. 2012, 23:50

if(preg_match('@<citation (.*)>(.*)<citation (.*)>(.*)<citation (.*)>(.*)<citation (.*)>(.*)</citation>(.*)</citation>(.*)</citation>(.*)</citation>@sU',$message))
Tu y es presque :D

maintenant observe bien une ouverture de citation simple :

Code : Tout sélectionner

<citation>
Et une avec le nom :

Code : Tout sélectionner

<citation nom="truc">
Quelle est la différence entre les deux ? Tu as pensé à :

Code : Tout sélectionner

nom="truc"
Et c'est très bien, mais n'as-tu pas oublié un tout petit détail qui explique ton souci ? quelquechose d'invisible... qu'on voit dans l'une mais pas dans l'autre... et qui devrait donc se retrouver dans la parenthèse si on veut capturer les deux :-*
if(!@work()){ Nespresso(); } else { what(); }
______________________________

Eléphant du PHP | 418 Messages

13 févr. 2012, 01:43

un espace?

c'est tout ce que je vois (enfin presque Oo) ^^

ViPHP
ViPHP | 2287 Messages

13 févr. 2012, 01:54

un espace?

c'est tout ce que je vois (enfin presque Oo) ^^
Eh ben oui :) Et il est où cet espace actuellement ? dans une partie optionelle (couverte par un *) ou la partie "en dur" de la regexp ?
if(!@work()){ Nespresso(); } else { what(); }
______________________________

Eléphant du PHP | 418 Messages

13 févr. 2012, 02:01

dans la partie optionnel

Ce qui fait que ça devrais être (\s.*) non?

ViPHP
ViPHP | 2287 Messages

13 févr. 2012, 02:06

dans la partie optionnel
Si tu en es toujours à la même version qu'au dessus, non, justement... Il était juste avant la parenthèse dans la dernière version que tu as postée ;)
Ce qui fait que ça devrais être (\s.*) non?
Ça pourrait marcher mais ce n'est même pas nécessaire, vu que le . peut remplacer n'importe quel caractère, c'est un caractère-joker. Le * est un quantifieur qui signifie "zéro ou plusieurs". Le motif .* peut donc attrapper absolument n'importe quoi... espace inclus :D
if(!@work()){ Nespresso(); } else { what(); }
______________________________

Eléphant du PHP | 418 Messages

13 févr. 2012, 02:09

ça fonctionne bien pour les nom, mais si je met 4 citations dont 1 simples, il me dit pas l'erreur.

Mis à part ce que je t'est dit plus haut, je ne vois pas ce que je pourrais faire pour les différentier.

Une solution?

Merci

Cordialement

ViPHP
ViPHP | 2287 Messages

13 févr. 2012, 02:12

ça fonctionne bien pour les nom, mais si je met 4 citations dont 1 simples, il me dit pas l'erreur.
Peux-tu montrer ta regexp actuelle stp ?
if(!@work()){ Nespresso(); } else { what(); }
______________________________

Eléphant du PHP | 418 Messages

13 févr. 2012, 02:18

La regex au moment ou j'ai poster le message:
if(preg_match('@<citation (.*)>(.*)<citation (.*)>(.*)<citation (.*)>(.*)<citation  (.*)>(.*)</citation>(.*)</citation>(.*)</citation>(.*)</citation>@sU',$message))
L'actuelle
if(preg_match('@<citation(\s)(.*)>(.*)<citation(\s)(.*)>(.*)<citation(\s)(.*)>(.*)<citation (\s)(.*)>(.*)</citation>(.*)</citation>(.*)</citation>(.*)</citation>@sU',$message))
J'ai pas beaucoup de maitrise des regex, je commence à peine à comprendre ^^

ViPHP
ViPHP | 2287 Messages

13 févr. 2012, 02:25

L'actuelle
if(preg_match('@<citation(\s)(.*)>(.*)<citation(\s)(.*)>(.*)<citation(\s)(.*)>(.*)<citation (\s)(.*)>(.*)</citation>(.*)</citation>(.*)</citation>(.*)</citation>@sU',$message))
J'ai pas beaucoup de maitrise des regex, je commence à peine à comprendre ^^
Ça va venir, on y travaille :)

Par contre :
Ce qui fait que ça devrais être (\s.*) non?
Ça pourrait marcher mais ce n'est même pas nécessaire, vu que le . peut remplacer n'importe quel caractère, c'est un caractère-joker. Le * est un quantifieur qui signifie "zéro ou plusieurs". Le motif .* peut donc attrapper absolument n'importe quoi... espace inclus :D
Je sais pas trop comment en me lisant tu t'es retrouvé à garder le \s et le mettre dans une parenthèse séparée ? Autant ta proposition initiale était bonne (au moins fonctionnelle) que là ben ça casse tout du coup, tu as rendu l'espace obligatoire à nouveau... :priere: C'est pourquoi les citations simples ne valident pas le masque.
if(!@work()){ Nespresso(); } else { what(); }
______________________________