YAML et la gestion des quotes

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : YAML et la gestion des quotes

par Hywan » 30 avr. 2007, 10:13

Hmm en effet.
Mais un truc dérange :
handle doit être un pointeur valide, et avoir été correctement ouvert par fopen(), popen(), ou fsockopen().
Ici, handle n'est pas une ressource mais une chaîne de caractères (car on n'a pas toujours des formes serializées en YAML quand même ^^).

Mais l'idée était bonne.
Pardon si j'ai pu être blaissant, mais il faudrait en dire plus la prochaine fois hehe ;-) (et je suis même pas sûr que c'était volontaire)

Bonne journée :)

par jojolapine » 29 avr. 2007, 22:49

array fgetcsv ( resource handle [, int length [, string delimiter [, string enclosure]]] )
?

par Hywan » 29 avr. 2007, 15:16

Il n'y a en effet aucun rapport avec CSV.
CSV (Comma-Separated Values) met en avant l'utilisation des séparateurs comme virgule et point-virgule. C'est le seul rapport que je vois.
Mais ça revient à donner la différence entre un pigeon.

Sinon concernant l'explode, j'utilise en fait preg_split('#, #', $var, -1, PREG_SPLIT_NO_EMPTY); -- pardon si je me trompe dans la syntaxe --, car explode() me retournerait même les cas vide (par exemple : a, b, ici on aura 0 => 'a', 1 => 'b', 2 => '', ce que je ne souhaite pas).
Mais oui, comme tu le soulignes, c'est écrit en C, et donc c'est plus rapide :)

Bonne journée à vous tous :)

par Xenon_54 » 29 avr. 2007, 07:10

Bonjour.

Je reformule ma question.

Imaginons que nous avons la chaîne :

Code : Tout sélectionner

aaaa, "bbbb", "cc"cc", "dd, dd", "e"e, ee"
On veut l'éclater pour avoir :

Code : Tout sélectionner

0 => aaaa 1 => "bbbb" 2 => "cc"cc" 3 => "dd, dd" 4 => "e\e, ee"
Vous comprendrez qu'un simple explode() ne suffit pas.

Comment feriez vous ? Je ne trouve pas, help :P


Merci.
YAML et CSV n'ont rien à voir :?
Moi je vois bien un rapport.

par Sékiltoyai » 28 avr. 2007, 22:54

Je ne travaille que avec les regex, donc (à vue de clavier) ça me paraît beaucoup plus rapide que de traiter caractère par caractère (dans ce cas ci).
Explode examine caractère par caractère, donc même si tu utilises une fonction pour te splitter tes chaines, elles le feront comme ca.
Par contre ces fonctions sont codées en C donc plus rapide.

par Hywan » 28 avr. 2007, 19:39

Haha je suis complètement dingue =P~ \:D/ |*() :mrgreen:

J'ai enfin réussi à gérer ces foutus quotes.
J'explique comme j'ai fais.

Je fais un explode par "virgule espace" (, ).
Donc je boucle mon tableau.
Si pour chaque début de chaîne j'ai un quote, je repère sa position, et je continue. Pour toutes les chaînes qui vont suivrent et qui ne se termine pas par " ou ' (attention s'il est échappé ou pas), on les ajoute à celle dont on a relevé la position. Puis on supprime la chaîne ajoutée.
Et comme ça marche nikel :]

On va me dire que c'est long.
Je répondrais alors non. Car ça reste un cas particulier. Et donc je ne le fais que très rarement.
Je ne travaille que avec les regex, donc (à vue de clavier) ça me paraît beaucoup plus rapide que de traiter caractère par caractère (dans ce cas ci).


Oui la formule (?(1)... correspond à une condition en PCRE (merci à Damien et Naholyr pour Lumadis.be ;-) il me sauve la vie très souvent hehe).
(?(1)a|b) correspond à : si l'instruction 1 est vrai (avec les parenthèses capturantes), alors on exécute a, sinon b. C'est pratique. Ici je n'ai pas de b, donc c'est juste (?(1)a|), j'admets que la première fois, c'est surprenenant.


Bonne nouvelle, il ne me reste que les multi-documents à gérer (ça va être rapide) et les clés numériques (et ça, c'est problématique).

Merci pour votre aide :) Le sujet est résolu ;-)

par Hubert Roksor » 28 avr. 2007, 14:29

un expression régulière est plus rapide qu'un traitement caractère par caractère n'est-ce pas ?
Si "caractère par caractère" signifie d'accéder à chaque caractère par sa position (par exemple $str[$i]) alors je dirais que la réponse est oui dans 99%. Sinon, ça dépend vraiment des cas. Tu as toute latitude pour optimiser ton propre parser et le spécialiser dans un usage particulier alors qu'il est impossible d'optimiser une expression régulière correctement construite. Ensuite, c'est un rapport temps/résultats, ça prend plus de temps à écrire aussi.

Rappelle-moi ce que doit faire exactement ta regex stp et je te ferai le parser à la strspn() qui correspond.

PS: je demande parce que je ne sais pas du tout ce que fait (?(1)) :roll: je vais regarder le manuel de ce pas
PPS: ok, donc c'est un conditionnal sans clause "false". À part ça j'ai regardé les specs de YAML et... lol. Il faudrait être dingue pour essayer de l'implémenter intégralement.

par naholyr » 28 avr. 2007, 14:01

Mais enlever moi d'un doute : un expression régulière est plus rapide qu'un traitement caractère par caractère n'est-ce pas ?
En général oui, mais c'est à tester tout de même. La piste donnée par Hubert permet d'optimiser drastiquement le parsing.

par Hywan » 28 avr. 2007, 13:01

Bonne nouvelle :]

Voici l'expression régulière qui règle le problème :

Code : Tout sélectionner

#(?:(?<!\\\)("|\'|))(.*)(?:(?(1)(?<!\\\)\1|)), #U
Il suffisait de capturer les quotes " et ', et aussi rien. Et dans ce cas, tout fonctionne bien :)

Mais enlever moi d'un doute : un expression régulière est plus rapide qu'un traitement caractère par caractère n'est-ce pas ?

Merci pour votre aide et pour vos idées :) J'ai découvert strcspn(), et strspn() que je ne connaissais pas. Merci :)

Bonne journée (bientôt, la publication du paquetage, pour les personnes intéressées).


PS : Elle ne résoud pas entièrement le problème, mais déjà une grosse partie. Je vais pouvoir faire le reste avec vos propositions :)

par Hywan » 28 avr. 2007, 12:50

Je souhaite encore persisté un petit peu sur les regex. Si jamais je n'y arrive pas, je passerai alors au traitement caractère par caractère.

Voilà où j'en suis (ça évolue un peu).
Comme le comportement de preg_split est très étrange, et qu'il accèpte très bizarrement les PCRE, j'ai décidé d'utiliser un preg_match_all, avec un tag U, on arrive presque au même comportement.

Voilà le code :
$a = '"Is", "Get, t\"ing", ';

preg_match_all('#(?:(?<!\\\)("|\'))(.*)(?:(?(1)(?<!\\\)\1|)), #U', $a, $m);

print_r($m);
On aura :

Code : Tout sélectionner

Array ( [0] => Array ( [0] => "Is", [1] => "Get, t\"ing", ) [1] => Array ( [0] => " [1] => " ) [2] => Array ( [0] => Is [1] => Get, t\"ing ) )
En revanche, si on a : Is, et pas "Is", ça ne fonctionne plus. Mais on s'en rapproche :P

par Hywan » 28 avr. 2007, 12:37

Hehe Hubert :)
Je ne compte pas faire concurrence à Symfony et compagnie.

C'est juste un parcours personnel, histoire d'améliorer mon niveau et mon cadre de développement.
Car, mine de rien, en faisant un Framework, qu'est-ce qu'on apprend !

Et accessoirement, s'il est apprécié, alors bon, c'est un bonus :)

Bon c'est parti alors, je vais encore me battre avec ce problème. Tayo.

par naholyr » 28 avr. 2007, 09:35

YAML et CSV n'ont rien à voir :?

par Hubert Roksor » 28 avr. 2007, 02:47

[sarcasme]
C'est rigolo, je me demandais justement ce qu'il manquait à PHP : un framework... :lol:
[/sarcasme]

par Xenon_54 » 28 avr. 2007, 00:00

par Hywan » 27 avr. 2007, 23:25

Je sais bien et je compte le concurrencer :lol:

Etant donné que je fais un Framework (et peut être un CMS à l'avenir), je me dois d'avoir un paquetage YAML :) Le support du framework (site) est en construction. Je vous ferai savoir quand il sortira hehe :wink:


Merci pour vos solutions. Je test tout ça demain, et je vous tiens au jus :)