Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

modifier une chaine seulement hors tags html

13 réponses
Avatar
Xavier Brochard
Bonjour

Je ne sais pas si mon titre est bien choisi mais voilà:

Dans un résultat de recherche, je veux "colorer" (avec un tag html) le motif
recherché.

Dans la plupart des cas le format de résultat contiendra du code html. Mais
ce code n'est pas déterminé à l'avance, soit parce qu'il fait partie du
résultat, soit parce qu'il détermine le format et est choisi lors du
paramétrage du bazar.
Parfois le motif recherché figure aussi dans le code html, et bien
évidemment il ne faut alors pas le "colorer".

Cette expression rationnelle fonctionne assez bien, mais pas tout le temps:

eval { $print =~ s/>[^<]+/&paintFoundText($&)/gei };

(la fonction paintFoundText se contente d'ajouter un tag <span class=found>
autour du motif trouvé)

Elle a l'avantage d'être simple, et de ne pas trop ralentir le programme,
pour une "feature" de peu d'importance.

En cherchant des trucs plus élaboré (mais peu probants), je finis par penser
qu'il faudrait faire beaucoup beaucoup plus compliqué. Mais alors j'ai peur
que ça consomme trop de ressources.

Qu'en pensez vous? et avez vous des pistes?

J'ai essayé d'être clair et pas trop long, mais comme mon niveau de Perl
est faible... si c'est du charabia, engueulez-moi.

cordialement,
xavier

10 réponses

1 2
Avatar
Nicolas George
Xavier Brochard wrote in message
<4c3af7c5$0$9211$:
En cherchant des trucs plus élaboré (mais peu probants), je finis par penser
qu'il faudrait faire beaucoup beaucoup plus compliqué. Mais alors j'ai peur
que ça consomme trop de ressources.

Qu'en pensez vous? et avez vous des pistes?



Il ne faut jamais manipuler directement du HTML sous forme de texte dans un
programme, c'est la porte ouverte à toutes les injections de code. Il faut
toujours manipuler le document sous forme d'arbre abstrait, et le convertir
en HTML textuel uniquement à la fin. Il y a plusieurs bibliothèques qui font
ça très bien.
Avatar
Xavier Brochard
Nicolas George wrote:

Xavier Brochard wrote in message
<4c3af7c5$0$9211$:
En cherchant des trucs plus élaboré (mais peu probants), je finis par
penser qu'il faudrait faire beaucoup beaucoup plus compliqué. Mais alors
j'ai peur que ça consomme trop de ressources.

Qu'en pensez vous? et avez vous des pistes?



Il ne faut jamais manipuler directement du HTML sous forme de texte dans
un programme, c'est la porte ouverte à toutes les injections de code. Il
faut toujours manipuler le document sous forme d'arbre abstrait, et le
convertir en HTML textuel uniquement à la fin. Il y a plusieurs
bibliothèques qui font ça très bien.



Mille pardon, je me suis mal exprimé:
le code html ne vient pas d'un formulaire (donc n'est pas entré par un
utilisateur), il vient d'un format de sortie qui a été paramétré d'avance,
mais qui varieras d'une installation à une autre.

En re-parcourant les archives de la liste, je crois qu'une liste convient
bien: d'abord on split sur les tags html (construction de la liste), puis on
modifie les éléments qui ne contiennent pas d'html (boucle for each avec un
match).

Merci pour le conseil cela dit.

xavier
Avatar
Olivier Miakinen
Bonjour,

Le 12/07/2010 14:33, Xavier Brochard répondait à Nicolas George :

Il ne faut jamais manipuler directement du HTML sous forme de texte dans
un programme, c'est la porte ouverte à toutes les injections de code. Il
faut toujours manipuler le document sous forme d'arbre abstrait, et le
convertir en HTML textuel uniquement à la fin. Il y a plusieurs
bibliothèques qui font ça très bien.



Mille pardon, je me suis mal exprimé:
le code html ne vient pas d'un formulaire (donc n'est pas entré par un
utilisateur), il vient d'un format de sortie qui a été paramétré d'avance,
mais qui variera d'une installation à une autre.



Je crois que tu t'étais bien exprimé, et que la réponse de Nicolas
reste valable avec ces précisions : plutôt que d'agir sur le HTML
généré, il vaudrait mieux agir sur le « format de sortie », juste
avant génération du HTML. Ce sera d'une part plus facile, et d'autre
part moins générateur de bug.

Cordialement,
--
Olivier Miakinen
Avatar
Xavier Brochard
Olivier Miakinen wrote:
Le 12/07/2010 14:33, Xavier Brochard répondait à Nicolas George :
Je crois que tu t'étais bien exprimé, et que la réponse de Nicolas
reste valable avec ces précisions : plutôt que d'agir sur le HTML
généré, il vaudrait mieux agir sur le « format de sortie », juste
avant génération du HTML. Ce sera d'une part plus facile, et d'autre
part moins générateur de bug.



J'aurais bien aimé que ce soit possible, mais ça ne l'est pas: le format de
sortie détermine ce qui est affiché.
Il s'agit en fait de requêtes dans une petite bases de donnés textuelle, le
"format de sortie" en liste de réponses indique le formatage html (ou pas)
et les champs affichés. Il y a un problème de conception initial qui empêche
d'agir avant le formatage de la sortie. Et je ne peux pas changer ça (pas
avant longtemps).

Merci pour la réponse, qui m'éclaire tout de même pas mal sur le défaut de
conception.

cordialement
xavier
Avatar
Olivier Miakinen
Le 12/07/2010 15:10, Xavier Brochard m'a répondu :

[...] il vaudrait mieux agir sur le « format de sortie », juste
avant génération du HTML. Ce sera d'une part plus facile, et d'autre
part moins générateur de bug.



J'aurais bien aimé que ce soit possible, mais ça ne l'est pas: le format de
sortie détermine ce qui est affiché.
Il s'agit en fait de requêtes dans une petite bases de donnés textuelle, le
"format de sortie" en liste de réponses indique le formatage html (ou pas)
et les champs affichés. Il y a un problème de conception initial qui empêche
d'agir avant le formatage de la sortie. Et je ne peux pas changer ça (pas
avant longtemps).



Bon, dans ce cas je vais répondre à ta proposition précédente.

Le 12/07/2010 14:33, Xavier Brochard avait écrit :

En re-parcourant les archives de la liste, je crois qu'une liste convient
bien: d'abord on split sur les tags html (construction de la liste), puis on
modifie les éléments qui ne contiennent pas d'html (boucle for each avec un
match).



Tu fais comme tu veux, mais méfie-toi quand même du fait que le texte à
remplacer pourrait se trouver, après avoir écarté les balises HTML,
dans un élément TITLE, ou un élément STYLE, où il ne faudrait pas faire
le remplacement, voire dans un élément SCRIPT, où remplacer pourrait
être parfois désirable et parfois dangereux.

Cordialement,
--
Olivier Miakinen
Avatar
Olivier Miakinen
Le 12/07/2010 15:37, je répondais à Xavier Brochard :

En re-parcourant les archives de la liste, je crois qu'une liste convient
bien: d'abord on split sur les tags html (construction de la liste), puis on
modifie les éléments qui ne contiennent pas d'html (boucle for each avec un
match).



Tu fais comme tu veux, mais méfie-toi quand même du fait que le texte à
remplacer pourrait se trouver, après avoir écarté les balises HTML,
dans un élément TITLE, ou un élément STYLE, où il ne faudrait pas faire
le remplacement, voire dans un élément SCRIPT, où remplacer pourrait
être parfois désirable et parfois dangereux.



Ah, il y a aussi les éléments OPTION et TEXTAREA qui posent problème. Je
ne sais pas si j'en oublie (mais c'est probablement le cas).
Avatar
Xavier Brochard
Xavier Brochard wrote:
En re-parcourant les archives de la liste, je crois qu'une liste convient




ce n'est pas très élégant, mais ça marche bien:

my @listHtml = split (/(<[^>s]+>)/,$print);
$print = "";
foreach $x (@listHtml) {
$x = &paintFoundText($x) if ($x !~ m/^</);
$print .= $x;
}
(la fonction paintFoundText se contente d'ajouter un tag <span class=found>
autour du motif trouvé)


xavier
Avatar
Xavier Brochard
Olivier Miakinen wrote:
méfie-toi quand même du fait que le texte à
remplacer pourrait se trouver, après avoir écarté les balises HTML,
dans un élément TITLE, ou un élément STYLE, où il ne faudrait pas faire
le remplacement, voire dans un élément SCRIPT, où remplacer pourrait
être parfois désirable et parfois dangereux.



oui en effet, j'ai posté trop vite...
il y a aussi IFRAME dont je devrai me méfier.

merci d'attirer mon attention là-dessus.

cordialement
xavier
Avatar
Olivier Miakinen
Le 12/07/2010 16:15, Xavier Brochard m'a répondu :

méfie-toi quand même du fait que le texte à
remplacer pourrait se trouver, après avoir écarté les balises HTML,
dans un élément TITLE, ou un élément STYLE, où il ne faudrait pas faire
le remplacement, voire dans un élément SCRIPT, où remplacer pourrait
être parfois désirable et parfois dangereux.



oui en effet, j'ai posté trop vite...
il y a aussi IFRAME dont je devrai me méfier.



Euh... IFRAME, je ne vois pas pourquoi il aurait besoin d'un traitement
particulier. Mais TITLE, STYLE, SCRIPT, OPTION et TEXTAREA, oui. Qui
plus est, le caractère '>' peut légitimement se trouver n'importe où en
dehors des balises, et le caractère '<' peut aussi se trouver dans un
élément SCRIPT, ce qui fait que ton split par expression rationnelle ne
suffit pas à gérer ces cas.

Seule solution viable : utiliser un parseur de HTML pour obtenir un
arbre abstrait représentant le document, faire tes petites manips sur
les feuilles de cet arbre (sauf bien sûr TITLE, STYLE, SCRIPT, OPTION et
TEXTAREA), et enfin regénérer un code HTML textuel à la fin. On en
revient à ce que conseillait Nicolas au début de ce fil.

Cordialement,
--
Olivier Miakinen
Avatar
Xavier Brochard
Olivier Miakinen wrote:
Seule solution viable : utiliser un parseur de HTML pour obtenir un
arbre abstrait représentant le document, faire tes petites manips sur
les feuilles de cet arbre (sauf bien sûr TITLE, STYLE, SCRIPT, OPTION et
TEXTAREA), et enfin regénérer un code HTML textuel à la fin. On en
revient à ce que conseillait Nicolas au début de ce fil.



CQFD! merci pour tous ces (bons) conseils

et puisque on en revient au début, est ce que ça ne va pas être un peu lourd
pour une "feature" de peu d'importance?


xavier
1 2