Bonjour,
Vous avez encore l'air de croire que les lazy quantifiers (ou ungreedy, ou reluctant) ne fonctionnent pas avec PHP... si c'est le cas, c'est que la lib PCRE sur laquelle le module PHP se base a changé. M'étonnerait fort.
En plus, je vous ai fait la démo que ça fonctionnait, en vous expliquant pourquoi ça sélectionnait également les <th>. "Lazy", ça ne veut pas dire que le moteur s'arrête à la première balise (le moteur ne sait même pas qu'il traite du HTML, hein), ça veut dire que le quantifier commence par sélectionner le moins de caractères possible, et si nécessaire (ie en cas d'échec de l'expression) le phénomène de backtracking (machine arrière) le forcera à essayer avec 1 caractère de plus, et ainsi de suite jusqu'au succès de l'expression, ou jusqu'à ce qu'il n'y ait plus rien à sélectionner (entrainant l'échec de l'expression).
Si le quantifier est greedy, c'est l'inverse : le moteur sélectionne le maximum de caractères possible, et en cas d'échec le backtracking le force à abandonner 1 caractère, puis 2, etc.
Si je fais le développement avec la chaîne <tr><th><td> (volontairement raccourci pour l'exemple) et l'expression (<tr.*?>)<td>
1ère étape :
<tr sélectionne <tr
.*? ne sélectionne aucun caractère comme l'y autorise son quantifier * qui est lazy, et le moteur enregistre la position pour un éventuel backtracking
><t sélectionne ><t
d ne sélectionne pas h, échec de l'expression donc backtracking
2è étape (à la position du backtracking, on ne se soucie pas du <tr déjà sélectionné)
.*? sélectionne >
> ne sélectionne pas < , échec donc backtracking
3è étape : .*? sélectionne ><, > ne sélectionne pas t, échec
4è étape : .*? sélectionne ><t, > ne sélectionne pas h, échec
5è étape : .*? sélectionne ><th, > sélectionne >, <td> sélectionne <td>, SUCCES !
On est pourtant en lazy : et alors ? le backtracking continue tant qu'il y a des possibilités. S'il y avait du contenu dans le th, et que l'élément soit bien formé, vous auriez encore plein d'échecs après l'étape 4, jusqu'à arriver au chevron fermant du </th>, ce chevron > validant le > qui suit le .*?
En fait, cette expression recherche un <tr suivi de près ou de loin pas un <td> précédé d'un chevron fermant (caractère "supérieur"). Absolument pas ce que PapyJP recherche.
En greedy, même combat sauf que .* sélectionne ><th><td>, et > échoue car on est en fin de chaîne. .* sélectionne alors ><th><td, > sélectionne > et < échoue car fin de chaîne. Je poursuis ?
Et encore, je vous fais l'exemple avec le <td> en fin de chaîne, rendez-vous compte dans un document HTML, le backtracking se poursuivra jusqu'au dernier <td> du document.
PapyJP a écrit :
En conclusion la réponse à ma question est :
Si, PHP accepte bien les expressions rationnelles ungreedy, mais "jusqu'à un certain point".
Non non, il les accepte tout le temps, il faut juste savoir ce qu'elles font exactement