Expressions régulières pour coloration syntaxique
Résolu/Fermé
Abyss
-
Modifié par Abyss le 17/04/2013 à 10:28
Mihawk Messages postés 4315 Date d'inscription mercredi 29 mars 2006 Statut Contributeur Dernière intervention 6 janvier 2015 - 18 avril 2013 à 16:50
Mihawk Messages postés 4315 Date d'inscription mercredi 29 mars 2006 Statut Contributeur Dernière intervention 6 janvier 2015 - 18 avril 2013 à 16:50
A voir également:
- Expressions régulières pour coloration syntaxique
- Telecharger nero express pour windows 10 - Télécharger - Gravure
- Excel coloration conditionnelle - Guide
- Hitfilm express pour pc - Télécharger - Montage & Édition
- Coloration temporaire pour Halloween ✓ - Forum Loisirs / Divertissements
- Expressions francaises - Forum Études / Formation High-Tech
6 réponses
Mihawk
Messages postés
4315
Date d'inscription
mercredi 29 mars 2006
Statut
Contributeur
Dernière intervention
6 janvier 2015
846
17 avril 2013 à 22:26
17 avril 2013 à 22:26
Hello,
Tu cherches à faire quelque chose de vraiment pas simple, et tu te heurtes à un problème connu et chiant : appliquer deux replace à un texte, sachant que chaque replace peut influer sur l'autre !
Dans ton cas je ferai ceci :
1/ Coloration des guillemets en bleu
2/ Coloration des commentaires en gris
3/ Remplacement des bleus indésirables par du gris
En gros pour 1/ et 2/ rien ne change.
Pour le 3/ je pensais à un truc du genre
Sachant que tu dois faire très attention à tes (.*).
En effet, si tu cherches par exemple "//.*//" et que ton texte est le suivant : "// bonjour // à tous //" alors le (.*) peut aussi bien contenir "bonjour" que "bonjour // à tous" tu vois ce que je veux dire ?
Tu cherches à faire quelque chose de vraiment pas simple, et tu te heurtes à un problème connu et chiant : appliquer deux replace à un texte, sachant que chaque replace peut influer sur l'autre !
Dans ton cas je ferai ceci :
1/ Coloration des guillemets en bleu
2/ Coloration des commentaires en gris
3/ Remplacement des bleus indésirables par du gris
En gros pour 1/ et 2/ rien ne change.
Pour le 3/ je pensais à un truc du genre
$tab = preg_replace("#\/\*(.*)color\:blue(.*)\/\*#", "/*$1color:grey$2*/", $tab);
Sachant que tu dois faire très attention à tes (.*).
En effet, si tu cherches par exemple "//.*//" et que ton texte est le suivant : "// bonjour // à tous //" alors le (.*) peut aussi bien contenir "bonjour" que "bonjour // à tous" tu vois ce que je veux dire ?
Mihawk
Messages postés
4315
Date d'inscription
mercredi 29 mars 2006
Statut
Contributeur
Dernière intervention
6 janvier 2015
846
18 avril 2013 à 09:53
18 avril 2013 à 09:53
À ce moment-là il faut supprimer l'utilisation du (.*) qui est beaucoup trop général. En fait la meilleure solution serait de ne pas utiliser de slash '/' dans tes commentaires afin d'être sûr qu'un slash marche la fin d'un commentaire. Tu remplaces ensuite (.*) par ([^/]*). De même il faut remplacer .* par [^<]* si tu veux ensuite détecter un "<span". etc. Exemple !
À tester car je ne suis pas sûr du dernier crochet !
$tab = preg_replace('#\/\*([^<]*)<span style="color:blue">([^<]*)</span>([^*\]*)/#msU', '/*$1$2$3/*', $tab);
À tester car je ne suis pas sûr du dernier crochet !
AbyssQuote
Messages postés
17
Date d'inscription
jeudi 18 avril 2013
Statut
Membre
Dernière intervention
18 avril 2013
18 avril 2013 à 10:23
18 avril 2013 à 10:23
Pas mieux.
Tu as oublié (par contre) de fermer le commentaire dans le pattern, ça m'a fait un petit bug. Et dans ton dernier [ ], tu mets un antislash sans / derrière, ce qui fait qu'il échappe le crochet de fermeture et que ça pète tout. :p
Ca donne ça :
Cela dit, ça ne marche pas mieux mais je ne comprends pas pourquoi, ça semble juste. Ca ne produit aucun résultat visible sur la page.
Tu as oublié (par contre) de fermer le commentaire dans le pattern, ça m'a fait un petit bug. Et dans ton dernier [ ], tu mets un antislash sans / derrière, ce qui fait qu'il échappe le crochet de fermeture et que ça pète tout. :p
Ca donne ça :
$tab = preg_replace('#\/\*([^<]*)<span style="color:blue">([^<]*)</span>([^*\/]*)\/\*#msU', '/*$1$2$3/*', $tab);
Cela dit, ça ne marche pas mieux mais je ne comprends pas pourquoi, ça semble juste. Ca ne produit aucun résultat visible sur la page.
Mihawk
Messages postés
4315
Date d'inscription
mercredi 29 mars 2006
Statut
Contributeur
Dernière intervention
6 janvier 2015
846
Modifié par Mihawk le 18/04/2013 à 10:44
Modifié par Mihawk le 18/04/2013 à 10:44
Au temps pour moi ce n'est pas un antislash mais un slash que je voulais mettre dans la dernier crocher. Il ne faut pas échapper dans les classes.:
Cela dit, avec ce code ton commentaire ne doit contenir ni '*' ni '/'
$tab = preg_replace('#\/\*([^<]*)<span style="color:blue">([^<]*)</span>([^*/]*)\/\*#msU', '/*$1$2$3/*', $tab);
Cela dit, avec ce code ton commentaire ne doit contenir ni '*' ni '/'
AbyssQuote
Messages postés
17
Date d'inscription
jeudi 18 avril 2013
Statut
Membre
Dernière intervention
18 avril 2013
18 avril 2013 à 10:47
18 avril 2013 à 10:47
En effet, au temps pour moi !
Malheureusement, ça ne fonctionne toujours pas. J'ai pensé que ça venait du fait qu'un */ pouvait se cacher dans les deux premières classes.
Du coup j'ai tenté :
$tab = preg_replace('#\/\*([^*/]*)<span style="color:blue">([^*/]*)</span>([^*/]*)\/\*#msU', '/*$1$2$3/*', $tab);
Mais c'est pas mieux.
Je commence à désespérer, les regex sont vraiment moins évidents que je pensais.
Malheureusement, ça ne fonctionne toujours pas. J'ai pensé que ça venait du fait qu'un */ pouvait se cacher dans les deux premières classes.
Du coup j'ai tenté :
$tab = preg_replace('#\/\*([^*/]*)<span style="color:blue">([^*/]*)</span>([^*/]*)\/\*#msU', '/*$1$2$3/*', $tab);
Mais c'est pas mieux.
Je commence à désespérer, les regex sont vraiment moins évidents que je pensais.
Mihawk
Messages postés
4315
Date d'inscription
mercredi 29 mars 2006
Statut
Contributeur
Dernière intervention
6 janvier 2015
846
18 avril 2013 à 10:49
18 avril 2013 à 10:49
L'exercice auquel tu t'essaye n'est pas simple.
Tu pourrais me passer un bout de texte à colorier ? Je vais tester ça en local.
Tu pourrais me passer un bout de texte à colorier ? Je vais tester ça en local.
AbyssQuote
Messages postés
17
Date d'inscription
jeudi 18 avril 2013
Statut
Membre
Dernière intervention
18 avril 2013
18 avril 2013 à 11:05
18 avril 2013 à 11:05
function getCLASSFormulaire($tab_param) {
/* Récupère tous les attributs de la classe dans un array */
$tab_attribut_detailles=getCLASSTableAttributDetailles();
if(!$tab_param['class_id']) {
$tab_param['class_id']=$tab_param['id'];
}
$data=getCLASSData($tab_param);
$tab_attribut_valeur=initAttributData($tab_attribut_detailles, $data);
$tab_fieldset['0']['legend']='LEGEND 0';
$tab_fieldset['0']['column']=0;
$tab_param_form['fieldset']=$tab_fieldset;
/* TRES UTILISE POUR LES FORMULAIRES MULTI CONTEXTE */
/* if($tab_param['page']) {
$tab_contexte['page']=$tab_param['page'];
}
*/
$tab_param_form['url_action_form']=getControlerSetLink(getCLASSClassId(),$tab_contexte);
$tab_param_form['id_retour']=$tab_param['id_retour'];
$tab_param_form['submit_value'] = $tab_param['submit_value'];
$tab_param_form['popup'] = $tab_param['popup'];
$tab_param_form['redirect'] = $tab_param['redirect'];
$tab_param_form['target_attribut_id'] = $tab_param['target_attribut_id'];
$tab_param_form['target_attribut_lib'] = $tab_param['target_attribut_lib'];
$tab_param_form['id_class']= 'CLASS';
/* $tab_param_form['titre']='Titre';
$tab_param_form['sous-titre']='Sous titre';
*/
$html=getPresentationFormulaire($tab_attribut_valeur,$tab_param_form);
return $html;
}
Tiens, par exemple. Merci beaucoup en tout cas. :)
/* Récupère tous les attributs de la classe dans un array */
$tab_attribut_detailles=getCLASSTableAttributDetailles();
if(!$tab_param['class_id']) {
$tab_param['class_id']=$tab_param['id'];
}
$data=getCLASSData($tab_param);
$tab_attribut_valeur=initAttributData($tab_attribut_detailles, $data);
$tab_fieldset['0']['legend']='LEGEND 0';
$tab_fieldset['0']['column']=0;
$tab_param_form['fieldset']=$tab_fieldset;
/* TRES UTILISE POUR LES FORMULAIRES MULTI CONTEXTE */
/* if($tab_param['page']) {
$tab_contexte['page']=$tab_param['page'];
}
*/
$tab_param_form['url_action_form']=getControlerSetLink(getCLASSClassId(),$tab_contexte);
$tab_param_form['id_retour']=$tab_param['id_retour'];
$tab_param_form['submit_value'] = $tab_param['submit_value'];
$tab_param_form['popup'] = $tab_param['popup'];
$tab_param_form['redirect'] = $tab_param['redirect'];
$tab_param_form['target_attribut_id'] = $tab_param['target_attribut_id'];
$tab_param_form['target_attribut_lib'] = $tab_param['target_attribut_lib'];
$tab_param_form['id_class']= 'CLASS';
/* $tab_param_form['titre']='Titre';
$tab_param_form['sous-titre']='Sous titre';
*/
$html=getPresentationFormulaire($tab_attribut_valeur,$tab_param_form);
return $html;
}
Tiens, par exemple. Merci beaucoup en tout cas. :)
Mihawk
Messages postés
4315
Date d'inscription
mercredi 29 mars 2006
Statut
Contributeur
Dernière intervention
6 janvier 2015
846
18 avril 2013 à 11:19
18 avril 2013 à 11:19
Essaye ces 4 lignes :
Attention, cela ne fonctionne qu'avec une seule expression entourée de guillemet dans les commentaires.
Genre dans "/* Bonjour "toi" et "moi" */" seul le "toi" sera gris.
$tab = preg_replace('#"([^"]*)"#','"<span style="color:blue">$1</span>"', $tab); $tab = preg_replace("#([a-zA-Z]{3,}|\s)'([^']*)'#",'$1\'<span style="color:blue">$2</span>\'', $tab); $tab = preg_replace('#\/\*([^*]*)\*\/#','<span style="color:grey">/*$1*/</span>', $tab); $tab = preg_replace('#\/\*([^<]*)<span style="color:blue">([^<]*)</span>(.*)\*\/#msU', '/*$1<span style="color:grey">$2</span>$3*/', $tab);
Attention, cela ne fonctionne qu'avec une seule expression entourée de guillemet dans les commentaires.
Genre dans "/* Bonjour "toi" et "moi" */" seul le "toi" sera gris.
AbyssQuote
Messages postés
17
Date d'inscription
jeudi 18 avril 2013
Statut
Membre
Dernière intervention
18 avril 2013
18 avril 2013 à 11:27
18 avril 2013 à 11:27
Ca me fait pas loin du contraire. Lorsqu'il rencontre un ' ou " dans un commentaire, il met la suite du commentaire en bleu. Et pour les guillemets et apostrophes en dehors des commentaires, ça me fait un truc bizarre.
$tab_fieldset['0']['legend'<span style="color:blue">]=</span>'LEGEND 0';
Mihawk
Messages postés
4315
Date d'inscription
mercredi 29 mars 2006
Statut
Contributeur
Dernière intervention
6 janvier 2015
846
18 avril 2013 à 11:30
18 avril 2013 à 11:30
Aie oui...
En fait pour éviter de colorier les apostrophe, je lui ai dit de prendre uniquement les guillemets précédé d'au moins 3 lettres (ça élimine les d', qu', c', etc...). Mais dans ce cas tout ce qui est ['montexte'] sera pris en compte...
La gestion des guillemets simples est vraiment galère.
En fait pour éviter de colorier les apostrophe, je lui ai dit de prendre uniquement les guillemets précédé d'au moins 3 lettres (ça élimine les d', qu', c', etc...). Mais dans ce cas tout ce qui est ['montexte'] sera pris en compte...
La gestion des guillemets simples est vraiment galère.
AbyssQuote
Messages postés
17
Date d'inscription
jeudi 18 avril 2013
Statut
Membre
Dernière intervention
18 avril 2013
18 avril 2013 à 11:34
18 avril 2013 à 11:34
En repartant de ma coloration des guillemets, apostrophes et commentaires et de ta recolorisation des guillemets dans les commentaires :
J'obtiens ce que tu voulais me montrer à la base. Juste la première quote en gris.
$tab = preg_replace('#\/\*([^<]*)<span style="color:blue">([^<]*)</span>(.*)\*\/#msU', '/*$1<span style="color:grey">$2</span>$3*/', $tab);
J'obtiens ce que tu voulais me montrer à la base. Juste la première quote en gris.
Mihawk
Messages postés
4315
Date d'inscription
mercredi 29 mars 2006
Statut
Contributeur
Dernière intervention
6 janvier 2015
846
18 avril 2013 à 12:01
18 avril 2013 à 12:01
Oui en fait le preg replace ne fonctionne pas dans notre cas... Il faudrait plutôt faire un "explode" de ton texte afin de traiter chaque partie indépendamment
AbyssQuote
Messages postés
17
Date d'inscription
jeudi 18 avril 2013
Statut
Membre
Dernière intervention
18 avril 2013
18 avril 2013 à 12:06
18 avril 2013 à 12:06
Je pensais que ça passerait avec un while, mais non plus.
Je suis très mauvais en algo, tu veux faire un explode(" ",$tab), ok. Et ensuite un foreach sur l'array obtenu ? Si oui, ça pose souci, parce que ma fonction prend un $string en entrée et retournera un array. Je suis pas sûr qu'il apprécie.
Je suis très mauvais en algo, tu veux faire un explode(" ",$tab), ok. Et ensuite un foreach sur l'array obtenu ? Si oui, ça pose souci, parce que ma fonction prend un $string en entrée et retournera un array. Je suis pas sûr qu'il apprécie.
Mihawk
Messages postés
4315
Date d'inscription
mercredi 29 mars 2006
Statut
Contributeur
Dernière intervention
6 janvier 2015
846
18 avril 2013 à 13:00
18 avril 2013 à 13:00
En fait, si tous tes commentaires sont au format /* ... */ (et pas en //) alors du peux faire un :
En gros tu éclates ta chaîne avec les "/*" ou les "*/" et tu génères un tableau.
À partir de ce moment-là, tu sais donc que :
$parts[0] : contient le début du texte
$parts[1] : contient le premier commentaire
$parts[2] : contient le texte entre les deux premiers commentaires
$parts[3] : contient le secondcommentaire
...
Donc les index pairs contiennent du texte normal et les index impairs du texte de commentaire. Dès lors tu peux reconstituer ton texte en appliquant les regexp qu'il faut.
Dis moi donc si ça tourne ^^
$parts = preg_split("#\/\*|\*\/#", $tab);
En gros tu éclates ta chaîne avec les "/*" ou les "*/" et tu génères un tableau.
À partir de ce moment-là, tu sais donc que :
$parts[0] : contient le début du texte
$parts[1] : contient le premier commentaire
$parts[2] : contient le texte entre les deux premiers commentaires
$parts[3] : contient le secondcommentaire
...
Donc les index pairs contiennent du texte normal et les index impairs du texte de commentaire. Dès lors tu peux reconstituer ton texte en appliquant les regexp qu'il faut.
$tab2 = ""; for ($i=0 ; $i<count($parts) ; $i++){ if ($i%2 == 0){ // Pair // Tu applique la regexp des guillemets $stringToAdd = preg_replace("#...#", "...", $parts[$i]); } else { // Impair > commentaire // Plus besoin de regexp : on colore en gris et on réinsère le pattern du split $stringToAdd = "<span style="color:grey;">/*" . $parts[$i] . "*/</span>"; } $tab2 .= $stringToAdd; }
Dis moi donc si ça tourne ^^
AbyssQuote
Messages postés
17
Date d'inscription
jeudi 18 avril 2013
Statut
Membre
Dernière intervention
18 avril 2013
18 avril 2013 à 14:45
18 avril 2013 à 14:45
Désolé, j'étais en pause bouffe. :[
Alors j'ai testé ton regex, ça m'a l'air de marcher !
Je l'ai adapté à mon code et le seul souci c'est qu'il me retourne deux fois mon code, une fois sans aucune mise en forme et une fois pile comme je le voulais. Un petit souci que je devrais pouvoir résoudre si je me penche un peu dessus.
En tout cas, merci infiniment !
Alors j'ai testé ton regex, ça m'a l'air de marcher !
$parts = preg_split('#\/\*|\*\/#', $tab); for ($i=0 ; $i<count($parts) ; $i++){ if ($i%2 == 0){ // Pair // Tu applique la regexp des guillemets $stringToAdd = preg_replace('#"(.*)"#msUi','<span style="color:blue">"$1"</span>', $parts[$i]); $stringToAdd = preg_replace('#\'(.*)\'#msUi','<span style="color:blue">"$1"</span>', $parts[$i]); } else { // Impair > commentaire // Plus besoin de regexp : on colore en gris et on réinsère le pattern du split $stringToAdd = '<span style="color:grey;">/*' . $parts[$i] . '*/</span>'; } $tab .= $stringToAdd; }
Je l'ai adapté à mon code et le seul souci c'est qu'il me retourne deux fois mon code, une fois sans aucune mise en forme et une fois pile comme je le voulais. Un petit souci que je devrais pouvoir résoudre si je me penche un peu dessus.
En tout cas, merci infiniment !
Mihawk
Messages postés
4315
Date d'inscription
mercredi 29 mars 2006
Statut
Contributeur
Dernière intervention
6 janvier 2015
846
18 avril 2013 à 14:48
18 avril 2013 à 14:48
Normalement mon code l'affiche une fois coloré.
S'il s'affiche 2 fois c'est que tu n'as pas supprimé un echo de ton côté je pense :)
S'il s'affiche 2 fois c'est que tu n'as pas supprimé un echo de ton côté je pense :)
AbyssQuote
Messages postés
17
Date d'inscription
jeudi 18 avril 2013
Statut
Membre
Dernière intervention
18 avril 2013
18 avril 2013 à 15:17
18 avril 2013 à 15:17
Au temps pour moi, j'avais supprimé ton $tab2="".
Ce que je trouve étrange c'est que lorsque je rajoute une simple ligne de code dans le pair :
Tout le bleu disparait au profit de function en violet.
Ce que je trouve étrange c'est que lorsque je rajoute une simple ligne de code dans le pair :
$stringToAdd = preg_replace('#(function)#msUi','<span style="color:purple">$0</span>', $parts[$i]);
Tout le bleu disparait au profit de function en violet.
AbyssQuote
Messages postés
17
Date d'inscription
jeudi 18 avril 2013
Statut
Membre
Dernière intervention
18 avril 2013
18 avril 2013 à 15:33
18 avril 2013 à 15:33
Je vois d'où ça vient. Ca réécrit par dessus. Pas de souci de ce côté là, suffit de le mettre à la suite. Merci encore !
Mihawk
Messages postés
4315
Date d'inscription
mercredi 29 mars 2006
Statut
Contributeur
Dernière intervention
6 janvier 2015
846
18 avril 2013 à 15:34
18 avril 2013 à 15:34
Avec ça ?
$stringToAdd = preg_replace('#(function)#i','<span style="color:purple">$1</span>', $parts[$i]);
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
AbyssQuote
Messages postés
17
Date d'inscription
jeudi 18 avril 2013
Statut
Membre
Dernière intervention
18 avril 2013
18 avril 2013 à 15:57
18 avril 2013 à 15:57
Pour ceux qui tomberont ici et qui comme moi ont galéré longtemps, je vous donne le code.
function replaceArray($tab){ // Mise en forme $tab = preg_replace('#;#',';<br/>', $tab); // Permet les retours à la ligne à la fin des commandes $tab = preg_replace('#{#','{<br/><BLOCKQUOTE>', $tab); // Permet les retours à la ligne et les tabulations lors des ouvertures d'accolades $tab = preg_replace('#}#','</BLOCKQUOTE>}<br/>', $tab); // Permet de supprimer les tabulations lors des fermetures d'accolades // Découpage de $tab en morceaux : le code et les commentaires $parts = preg_split('#\/\*|\*\/#', $tab); $tab=''; // On vide tab // Pour chaque morceau, on vérifie s'il s'agit de code ou de commentaire for ($i=0 ; $i<count($parts) ; $i++){ if ($i%2 == 0){ // Pair, c'est du code // Quotes en bleu, on fait les modifications voulues sur notre morceau de code $parts[$i] = preg_replace('#"(.*)"#msUi','<span style="color:blue">$0</span>', $parts[$i]); $parts[$i] = preg_replace('#\'(.*)\'#msUi','<span style="color:blue">$0</span>', $parts[$i]); } else { // Impair, c'est du commentaire // Commentaires en gris $parts[$i] = '<span style="color:grey;"><br/>/*' . $parts[$i] . '*/<br/></span>'; } $tab .= $parts[$i]; // Et on affecte notre morceau à tab, jusqu'à la fin de notre code } return $tab; }
AbyssQuote
Messages postés
17
Date d'inscription
jeudi 18 avril 2013
Statut
Membre
Dernière intervention
18 avril 2013
18 avril 2013 à 16:00
18 avril 2013 à 16:00
Par contre, j'étais en invité quand j'ai posté le sujet. Si un gentil modérateur/admin pouvait le passer en résolu, ce serait fort gentil !
Encore merci à Mihawk. Je te ferai une statue dans mon prochain jeu. o/
Encore merci à Mihawk. Je te ferai une statue dans mon prochain jeu. o/
18 avril 2013 à 09:44
J'étais arrivé à quelque chose comme ça, oui.
Le souci étant que dans le cas où on trouve quelque chose comme ça :
Eh bien... le regex considère le premier /* et le dernier */. Donc le premier bout de code subit aussi la suppression du color:blue et c'est pas chouette.
J'ai pas encore trouvé comment faire. Au début, j'avais pensé exclure les caractères */ de $1, $2 et $3, mais j'ai pas réussi à faire quelque chose de fonctionnel.
18 avril 2013 à 09:48