|
| |
|
14 décembre 2006 16:50
|
Filtres de test et REGEXPs - Implémenté ou pas dans SPIP 1.9.1 ?
J’ai trouvé une piste avec l’article de mortimer "Comment savoir si un article est virtuel" (http://www.spip-contrib.net/Comment...).
Il décrit comment créer un filtre qui permette de gérer les regexps. Ca fonctionne bien, mais quand la regexp contient des paranthèses, ça plante...
|
marabbeh
25 janvier 2007 14:45
|
Filtres de test et REGEXPs - Implémenté ou pas dans SPIP 1.9.1 ?
J’utilise couramment des regexps dans mes filtres, avec les versions 1.9.1 et 1.9.2b3, et les () ne posent pas de pb.
|
|
marino
20 février 2007 00:44
|
Filtres de test et REGEXPs - Implémenté ou pas dans SPIP 1.9.1 ?
Ben si, "ça" pose des problèmes.
Lorsque l’on essaie une syntaxe du style :
[(#ID_RUBRIQUE|==ACC^(1|2|3|8|9|12)$ACC|ACCBlah blah,ACC)]
Remplacez les "ACC" par des accolades, puisque visiblement le machin qui gère ce forum consacré à SPIP les interdit.
Bref, on se récolte une erreur du type :
Warning : mb_ereg() [function.mb-ereg] : mbregex compile err : premature end of char-class in /var/www/vhosts/ucjg.fr/subdomains/refonte/httpdocs/ecrire/public/phraser_html.php on line 339 (ou 376)
Le plus fort, c’est que le phraser_html (m..., un terme anglo-saxon dans SPIP - qui est l’immonde traître qui...) n’utilise pas de fonctions multibytes mb_ereg()... Premier mystère. Passons.
En chouffant le code du phraseur_html, on s’aperçoit que l’erreur -qui n’est pas systématique mais semble relever d’un effet de bord- remonte aux lignes 31 et 32 :
# ecriture alambiquee pour rester compatible avec les hexadecimaux des vieux squelettes
define(’NOM_DE_CHAMP’, "#((" . NOM_DE_BOUCLE . ") :) ?(([A-F]*[G-Z_][A-Z_0-9]*)|[A-Z_]+)(\*ACC0,2ACC)") ;
define(’CHAMP_ETENDU’, ’\[([^]\[]*)\(’ . NOM_DE_CHAMP . ’([^[)]*\)[^]\[]*)\]’) ;
L’ennuyeux, c’est que cette regexp ne semble pas concerner la tokenization des filtres de test, mais celle d’un "CHAMP_ETENDU" dont je n’entrevois même pas ce qu’il peut être. Deuxième mystère. Passons.
De toute façon, il ne faut pas trop se faire d’illusions : de la façon dont ce phraseur tokenize les boucles SPIP, il y a fort à parier qu’intégrer des regexp avec le filtre décrit dans l’article de mortimer "Comment savoir si un article est virtuel" cité plus haut est une impasse. Cela tient au simple fait que la syntaxe des boucles SPIP utilisent des caractères de contrôles des regexp, comme [, ], (, ), ACC. L’erreur vient du fait que le tokenizer semble se mélanger les pinceaux quand on lui donne une regexp à la place d’une valeur si cette regexp utilise les caractères précités - et c’est pas glop.
Sincèrement, j’espère me tromper. Je n’ai ni le niveau ni la connaissance des tripes de SPIP pour avoir une vision d’ensemble. Je vais continuer mes tests, car le filtre de test sans le support des regexp, c’est un couteau sans lame auquel il manque le manche.
Si au passage, quelqu’un pouvait me dire comment nettoyer les lignes 31 et 32 de la syntaxe des "vieux squelettes"...
|
|
marino
20 février 2007 11:39
|
Filtres de test et REGEXPs - Implémenté ou pas dans SPIP 1.9.1 ?
Je confirme : les regexp fonctionnent dans le fitre de test tant que l’on utilise ni les paranthèses, ni les crochets :
Les crochets bloquent la tokenisation et l’exécution du test, ce qui a pour effet d’afficher le code du test.
les paranthèses et les accollades provoquent une "erreur dans le squelette" si elles sont utilisée en même temps, ainsi (remplacez les "ACC" par des accollades) :
/(\w)/ passe
/\wACC1ACC/ passe
/(\w)ACC1ACC/ provoque une erreur
Donc, méfiance. Il ya aurait un biais -il y a toujours un biais- qui consisterait à utiliser à la place des crochets, des paranthèses et des accollades d’autres caractères (l’UTF-8 en est plein), et des les remplacer à la volée dans le filtre de mortimer. Je fais un test et vous en recause.
Et, oh, je m’aperçois à l’instant que la virgule aussi casse la tokenisation.
Fight on, PHP warrior !
|
|
marino
20 février 2007 11:49
|
Filtres de test et REGEXPs - Implémenté ou pas dans SPIP 1.9.1 ?
Eh ben voilà, ça marche...
En fait, il "suffit" d’écrire ses regexps avec des caractères rares à la place des paranthèses, accollades, crochets et virgules.
Exemple :
“ = [
” = ]
‹ = (
› = )
‘ = Accollade ouvrante
’ = Accollade fermante
, = ∴
Ce qui nous donne une jolie regexp comme :
/‹“\w”‘1∴’›/
à la place de :
/([\w]ACC1,ACC)/ (remplacer les "ACC" par des accollades)
Modifiez le filtre de mortimer :
function expreg($text, $match)
ACC ouvrante
$match=preg_replace("/“/","[",$match) ;
$match=preg_replace("/”/","]",$match) ;
$match=preg_replace("/‹/","(",$match) ;
$match=preg_replace("/›/",")",$match) ;
$match=preg_replace("/‘/","ACC ouvrante",$match) ; A remplacer
$match=preg_replace("/’/","ACC fermante",$match) ; A remplacer
$match=preg_replace("/∴/",",",$match) ;
return preg_match($match, $text) ;
ACC fermante
Qu’est ce qu’on se marre. C’est parfois un peu surréaliste. J’ai ajouté une lame et un manche, mais je ne suis pas sûr d’avoir un bon couteau. Un pis aller en attendant mieux, tout au plus.
|
|
marino
21 février 2007 15:50
|
Filtres de test et REGEXPs - Implémenté ou pas dans SPIP 1.9.1 ?
Ca se complique. Le filtre fonctionne maintenant à merveilles (j’ai poussé mes tests assez loin), mais je continue à avoir l’erreur :
Warning : mb_ereg() [function.mb-ereg] : mbregex compile err : premature end of char-class in /var/www/vhosts/ucjg.fr/subdomains/refonte/httpdocs/ecrire/public/phraser_html.php on line 339
Warning : mb_ereg() [function.mb-ereg] : mbregex compile err : premature end of char-class in /var/www/vhosts/ucjg.fr/subdomains/refonte/httpdocs/ecrire/public/phraser_html.php on line 376
J’ai posé la question sur le forum : http://forum.spip.org/fr_189725.html
Il doit s’agir d’une config serveur, mais laquelle ?
|
|
marino
1er mars 2007 01:12
|
Filtres de test et REGEXPs - Implémenté ou pas dans SPIP 1.9.1 ?
Il semblerait bien que l’erreur vienne des regexp ’CHAMP_ETENDU’, ’BALISE_INCLURE’,’SQL_ARGS’ qui se trouvent au début de phraser_html.php.
J’utilise jEdit qui est compatible POSIX pour les regexp. Tester ([^[)]*\)[^]\[]*) comme regexp le fait planter avec un message "gnu.regexp.REException : At position 3 in regular expression pattern :
expected end of character class" qui rappelle le message d’erreur du début de ce thread.
Il faudrait échapper par des backslash tous les caractères réservés utilisés dans la classe de caractères ([^\[\)]*\)[^\]\[]*) afin d’avoir une regexp correcte...
L’ennui, c’est que ça ne fonctionne pas. Tout le phraser_html.php plante, car les regexp correctes ne matchent pas.
J’ai testé les regexp corrigées dans plusieurs testeur en ligne et dans plusieurs éditeurs. Tous sans exception on fait apparaître la nécessité d’échapper les caractères réservés. Va comprendre, Charles.
Pour ceux que ça intéresserait de tester, les quatre lignes modifiées sont les suivantes :
define(’SPEC_BOUCLE’,’/\s*\(\s*([^\s)]+)(\s*[^\)]*)\)/’) ;
[...]
# ecriture alambiquee pour rester compatible avec les hexadecimaux des vieux squelettes
define(’NOM_DE_CHAMP’, "#((".NOM_DE_BOUCLE.") :) ?(([A-F]*[G-Z_][A-Z_0-9]*)|[A-Z_]+)(\*ACC0,2ACC)") ;
define(’CHAMP_ETENDU’, ’\[([^\]\[]*)\(’ . NOM_DE_CHAMP . ’([^\[\)]*\)[^\]\[]*)\]’) ;
define(’BALISE_INCLURE’,’1]*(\(([^\)]*)\)) ?’) ;
define(’SQL_ARGS’, ’(\([^\)]*\))’) ;
En n’oubliant pas de remplacer les "ACC" par des accollades et les apostrophes "curly" par des apostrophes simples. Il y aurait également une palanquée de regexp dans le même cas ailleurs dans le script phraser_html.php
Amitiés à tou(te)s
|
|
marino
1er mars 2007 01:18
|
Filtres de test et REGEXPs - Implémenté ou pas dans SPIP 1.9.1 ?
>> http://forum.spip.org/fr_189725.htm...
Le tout vient peut-être d’une différence de flavor entre les regexp POSIX et PERL...
|
|
spipopup
6 avril 2007 11:50
|
Filtres de test et REGEXPs - et Spip 1.8 ?
vous parlez de 1.9. Y a t-il des difference’s avec 1.8 (les regexp sont d’après la doc utilisable avec 1.8) ?
j’utilise une regexp dans un critere :
BOUCLE_nomliste1 (ARTICLES) -id_rubrique=19 - - titre==^[#_titre_alpha:TEXTE] - - par titre -
ou - = accolade
le debug me donne :
SELECT articles.id_article, articles.descriptif, articles.soustitre, articles.titre, articles.lang
FROM spip_articles AS articles
WHERE (articles.id_rubrique = ’19’)
AND (articles.titre REGEXP ’Z’) ...AU LIEU DE REGEXP ’^Z’
AND articles.statut=’publie’
ORDER BY articles.titre
ce qui signifie que ni ^ (qui prend le 1er caractere d’un mot) ni d’ailleurs [ ] (qui séparent les caracteres) ne sont pris en consideration
mais au vu des messages postés ça et là, j’ai l’impression que ça marche ailleurs...
http://www.spip-contrib.net/Creer-u...
|
|
Marino
7 avril 2007 11:13
|
Filtres de test et REGEXPs - Implémenté ou pas dans SPIP 1.9.1 ?
BOUCLE_nomliste1 (ARTICLES) -id_rubrique=19 - - titre==^[#_titre_alpha:TEXTE] - - par titre -
... Wow ! Utiliser une balise SPIP comme pattern d’une regexp, c’est gonflé ;-)
Avez vous essayé :
BOUCLE_nomliste1 (ARTICLES) -id_rubrique=19 - - titre==(^[#_titre_alpha:TEXTE]) - - par titre -
En fait, j’en reviens à ce que je disais plus haut. J’ai un peu peur que les parser ne s’emmèle les peinceaux. Les [] qui entourent le #_titre_alpha:TEXTE sont les marqueurs de classe de caractères ? En l’état, la regexp signifierait "Toutes les chaînes de caractères qui commencent par une des lettres présentes dans la chaîne #_titre_alpha:TEXTE". C’est bien ça ?
|
|
Marino
7 avril 2007 11:38
|
Filtres de test et REGEXPs - Implémenté ou pas dans SPIP 1.9.1 ?
Au juste, avez vous testé en remplaçant #_titre_alpha:TEXTE par une valeur quelconque ?
BOUCLE_nomliste1 (ARTICLES) -id_rubrique=19 - - titre==^[a-e] - - par titre -
Est-ce que le ^ est pris en compte ?
|
|
spipopup
10 avril 2007 11:59
|
Filtres de test et REGEXPs
Bonjour Marino et merci pour les reponses,
Effectivement, c’est assez gonflé. Le mérite en revient à Claude D qui a créee une chouette contrib très ingénieuse pour fabriquer un index alphabetique sur les articles :
http://www.spip-contrib.net/Creer-u...
en 2 mots, il s’agit de créer des brèves qui ont chacune pour titre une lettre de l’alphabet. Dans le texte on place les caractères accentués et les majuscules ;
ainsi, #_titre_alpha:TITRE appelle la lettre concerné et #_titre_alpha:TEXTE appelle la lettre sous toutes ses formes, majuscule et accentué.
Le critère titre==^[#_titre_alpha:TEXTE] permet donc
de verifier si le titre de l’article concerné commence bien par la lettre (avec ^)
de lister toutes les formes possibles de la lettre (majuscule et accentuée), une à une (avec [ ])
Si ça semble très bien marcher chez certains, pas chez moi, et c’est l’ecriture de l’expression régulière qui coince.
si je place titre==^[e] ou titre==(^[e]), pour prendre l’exemple d’une lettre au hasard : discrimination sur la lettre sans majuscule et caracteres accentués.
Résultat : j’obtiens tous les articles commençant par "e", mais du coup hors boucle, hors contexte alphabetique.
Si je place titre==^[#_titre_alpha:TITRE] ou titre==(^[#_titre_alpha:TITRE])
Résultat : j’obtiens tous les articles où la lettre apparait, quelque soit sa position. C’est comme si ^n’est plus pris en compte.
si je place titre==^[#_titre_alpha:TEXTE] ou titre==^[eEéÉ] ou titre==(^[#_titre_alpha:TEXTE)] : je n’obtiens rien car [ ] qui liste les caracteres un à un n’est pas pris en compte.
voilà j’espere avoir été explicite, si vous avez des questions n’hésitez pas.
|
|
13 avril 2007 13:00
|
Filtres de test et REGEXPs - Implémenté ou pas dans SPIP 1.9.1 ?
Aaaaah ! Ben oui mais c’est sans compter sur le parser de boucles...
Quand tu écris titre=(^[#_titre_alpha:TEXTE]) -avec les accolades, bien sûr, que doit comprendre le parser ?
titre=(^[#_titre_alpha:TEXTE]) -> Les crochets sont des délimiteurs de classe de caractères de regexp. Je substitue la balise, et puis passe le relai à ce qui doit analyser l’expression entre accollades.
titre=(^[#_titre_alpha:TEXTE]) -> Les crochets sont des délimiteurs de balises, mais il y a une erreur de syntaxe, car les parathèses sont absentes. Je ne prends pas les crochets en compte. Je substitue la balise, et puis passe le relai à ce qui doit analyser l’expression entre accollades.
Je ne serais pas surpris que la syntaxe que tu utilise ne déclenche un effet de bords dans les phraser_html.php, et que l’analyse du tout soit aléatoire, voire dépende des versions de SPIP. Le phraser est un script massivement récursif, mais on ne peut pas indéfiniment imbriquer des niveaux de syntaxes.
Imagine :
µtitre=(^[[(#_titre_alpha:TITRE|==µ^[A-E]$µ| ?µ’ partie1’,’ partie2’µ)])µ
en remplaçant le "µ" par des accolades. Cela donne un filtre multicritères, multiniveaux. J’ai essayé, les résultats sont généralement décevants.
J’ai bien peur qu’il n’y ait pas de solution à ton problème. C’est pousser SPIP dans des retranchements pour lesquels il n’a pas été prévu.
|
|
spipopup
15 avril 2007 19:56
|
Filtres de test et REGEXPs
Mille mercis Marino pour le partage de ton savoir. Tes explications sont limpides.
Je ne peux de toute façon que constater que ça ne fonctionne pas. J’ai donc utilisé une boucle par lettre sans faire appel a la syntaxe non ambigues #_boucle:TEXTE. C’est long, moche et pas très glorieux, mais ça marche sur spip 1.8.
Reste que d’autres ont reussi ?!?
encore merci !
|
|
16 avril 2007 10:15
|
Filtres de test et REGEXPs - Implémenté ou pas dans SPIP 1.9.1 ?
Laissons la gloire aux héros : ils ne vivent jamais très vieux ;-)
|
|
marino
19 avril 2007 13:48
|
Filtres de test et REGEXPs - Implémenté ou pas dans SPIP 1.9.1 ?
Par contre, il y a un cas où ta syntaxe du début fonctionne : celui d’un passage par paramètre lors d’un include.
Essaie par exemple (les § sont à remplacer par des accollades) :
Appel [(#_BOUCLE_rubrique_principal:ID_RUBRIQUE|expreg§/^5/§| ?§[(#INCLURE§fond=inc-hebergementsTouristiques§§id_rubrique§)],§)]
Dans le squelette inc-hebergementsTouristiques.html, tu peux utiliser :
Avec la nouvelle syntaxe des INCLURE de SPIP 1.9+, le squelette appelé est inclu d’abord et analysé ensuite alors qu’avant, c’était le contraire (ou l’inverse ou un autre truc qui n’a rien à voir - m’en tape si ça fonctionne).
Tu peux donc écrire :
La balise #ID_RUBRIQUE est substituée lors de l’inclusion, avant l’interprétation du squelette recomposé. Je l’utilise sur le site que je construit actuellement.
|
|
amaury
7 août 2008 19:39
|
Filtres de test et REGEXPs - Implémenté ou pas dans SPIP 1.9.1 ?
Je remonte un peu dans le fil de la discussion :
A propos des expressions régulières qui ne passent pas dans les critères de boucles, je n’ai pas été voir comment fonctionne le parseur de SPIP, mais j’ai réussi à faire passer une regex sur spip 192d en utilisant le filtre concat sur la balise #ENV qui fournit la valeur à tester.
J’ai l’impression que le fait de filtrer cette balise la sort en quelque sorte des écueils de parsing puisqu’elle est évaluée après les accolades, crochets et autres charactères SPIP.
Par exemple :
<BOUCLE_test{champ == #ENV{var}|concat{'[^,]{2}'} }></BOUCLE_test>
Au besoin on peut aussi se passer de concat et utiliser #REM ou #NOOP et le filtre ’sinon’ pour pouvoir commencer à concaténer
<BOUCLE_test{champ ==#REM|sinon{'[^,]{2}'}></BOUCLE_test>
ça reste un peu compliqué mais je crois que ça passe...
Quelqu’un pour confirmer ?
|
|
amaury
7 août 2008 19:54
|
Filtres de test et REGEXPs - Implémenté ou pas dans SPIP 1.9.1 ?
je me réponds à moi-même : ça n’a pas l’air de mieux marcher finalement :(
|
|
Marino
8 août 2008 16:51
|
Filtres de test et REGEXPs - Implémenté ou pas dans SPIP 1.9.1 ?
Sans vouloir être trop pessimiste, les syntaxes des boucles SPIP utilisent beaucoup des caractères réservés des REGEXP, et il est un peu désespéré de penser arriver à une approche "propre".
Je continue d’utiliser ma fonction de substitution des caractères, mais je comprends que ce n’est pas "propre".
Dans une future version de SPIP, peut-être...
Marino
http://markup.fr
|
|