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

"parser" un texte entre dans un formulai re

6 réponses
Avatar
Will
bonjour.

"parser" est surement un bien grand mot pour ce que je veux faire...
voilà mon problème :
j'ai un texte de formualire, que je traite avec un script php. je
souhaite que chaque ligne du texte transformé soit entourée de balises
<p> et </p>. en charchant un peu, j'ai trouvé qu'avec ça, ça marche bien :
$texte = "<p>" .
preg_replace("'([\r\n])[\s]+'","</p>\n<p>",$_POST["texte"]) . "</p>";

je connais un peu les expressions régulières (disons que j'arrive plus
ou moins à les lire, mais j'ai quand même beaucoup de mal à les
fabriquer, surtout les regexp de perl), j'ai trouvé ça sur la doc en
ligne de nexen.com.

maintenant, je voudrais que si une balise se trouve sur une ligne (je
mettrai toujours la balise seule sur la ligne, donc la ligne se commence
par < et se finit par > ), il n'y ait pas ce formatage.

il doit surement y avoir une solution simple à ça, j'imagine à base de
preg_replace... (là je pensais à faire ce que je fais ci-dessus, puis
regarder sur chaque ligne s'il y a "<p><" en début de ligne, et
remplacer la ligne par le truc qu'il faut... mais je sais pas faire :) ).

--
Will

6 réponses

Avatar
Olivier Miakinen

j'ai un texte de formualire, que je traite avec un script php. je
souhaite que chaque ligne du texte transformé soit entourée de balises
<p> et </p>. en charchant un peu, j'ai trouvé qu'avec ça, ça marche bien :
$texte = "<p>" .
preg_replace("'([rn])[s]+'","</p>n<p>",$_POST["texte"]) . "</p>";


Tout d'abord, par défaut le caractère '.' ne remplace pas les fins de
lignes, donc tu pourrais obtenir la même chose comme ceci :
$texte = preg_replace("'.*'", "<p>$0</p>", $texte);

Note que ceci est équivalent à :
$texte = preg_replace("'[^n]'", "<p>$0</p>", $texte);
(je ne m'occupe pas des r qui ne devraient pas se trouver dans $_POST)

maintenant, je voudrais que si une balise se trouve sur une ligne (je
mettrai toujours la balise seule sur la ligne, donc la ligne se commence
par < et se finit par > ), il n'y ait pas ce formatage.


Maintenant, comme tu vas vouloir traiter des cas plus complexes, le
mieux serait de passer en option multiligne :
http://fr.php.net/manual/fr/reference.pcre.pattern.modifiers.php
$texte = preg_replace("'^.*$'m", "<p>$0</p>", $texte);

Tu ne veux traiter que les lignes qui ne commencent pas par '<' ? Rien
de plus simple :
$texte = preg_replace("'^[^<].*$'m", "<p>$0</p>", $texte);

Et tu peux même traiter les cas où la ligne ne commence pas par '<' mais
contient un '<', c'est un caractère de moins :
$texte = preg_replace("'^[^<]*$'m", "<p>$0</p>", $texte);

Enfin, si tu veux en profiter pour virer les espaces de début et de fin
de ligne :
$texte = preg_replace("'^[s]*([^<s]*)[s]*$'m", "<p>$1</p>", $texte);

Le seul risque, c'est de transformer aussi les lignes vides : je te
laisse remplacer un '*' par un '+' pour éviter cela.

Avatar
Will
Le 26/03/2005 19:26 (à peu de choses près), Olivier Miakinen a
intelligemment dit...
$texte = preg_replace("'.*'", "<p>$0</p>", $texte);


ah ouais. après avoir relu trois fois (voire plus en fait) tout le
message, avoir parcouru en diagonale
http://fr.php.net/manual/fr/reference.pcre.pattern.syntax.php, et
compris tous les exemples suivants, je me rends compte qu'en fait le
seul truc que je crois pas avoir déjà vu ailleurs c'est le $0. par
défaut, chaque suite de caractère qui répond au masque se retrouve dans
$0 ? et les apostrophes, ils servent à qqch ?

(je ne m'occupe pas des r qui ne devraient pas se trouver dans
$_POST)


ouais, c'est ce que je pensais aussi. on les trouve où ces caractères ?

d'ailleurs, ça me fait penser qu'au départ j'avais bêtement essayé
str_replace("n","</p>n<p>",$_POST["texte"]), et ça n'a jamais
fonctionné. est ce que y a une raison ou est ce que c'est moi qui craque ?

$texte = preg_replace("'[^n]'", "<p>$0</p>", $texte); [puis plus
loin : ] $texte = preg_replace("'^.*$'m", "<p>$0</p>", $texte);


ok. mais pourquoi on met une étoile dans le deuxième et pas dans le
premier ? et "'.*'m", ça marche non ? (mais c'est juste parce que c'est
simple, c'est ça ?)

Tu ne veux traiter que les lignes qui ne commencent pas par '<' ?
Rien de plus simple :
$texte = preg_replace("'^[^<].*$'m", "<p>$0</p>", $texte);


que dire de plus ? c'est exactement ce que je voulais :)

et on peut pas écrire "'[^<].*'" ? le résultat serait pas le même ? j'ai
bien lu ton lien, très instructif, mais je suis pas sur d'avoir bien
compris l'intérêt du m, à part que le ^ et le $ ne sont plus des
fin-début de ligne :)

Et tu peux même traiter les cas où la ligne ne commence pas par '<'
mais contient un '<', c'est un caractère de moins :
$texte = preg_replace("'^[^<]*$'m", "<p>$0</p>", $texte);


juste pour savoir si j'ai bien compris : ici, le * s'applique à "pas de
<" ? (je comprends toujours pas pourquoi on pourrait pas mettre
"'[^<]*'" tout simplement...)

Enfin, si tu veux en profiter pour virer les espaces de début et de
fin de ligne :
$texte = preg_replace("'^[s]*([^<s]*)[s]*$'m", "<p>$1</p>",
$texte);


alors ici, le $1 est mis pour la classe du milieu ? le $0 existe
toujours, égal au total de la ligne ?

Le seul risque, c'est de transformer aussi les lignes vides : je te
laisse remplacer un '*' par un '+' pour éviter cela.


oui en effet, il faut que je fasse cela.

merci beaucoup pour tout ces renseignements.

ps : j'ai écrit le message en plusieurs fois, j'ai relu mais c'est
possible que des fois ce soit pas très logique ce que je dis :)
--
Will

Avatar
Olivier Miakinen

ah ouais. après avoir relu trois fois (voire plus en fait) tout le
message, avoir parcouru en diagonale
http://fr.php.net/manual/fr/reference.pcre.pattern.syntax.php, et
compris tous les exemples suivants, je me rends compte qu'en fait le
seul truc que je crois pas avoir déjà vu ailleurs c'est le $0. par
défaut, chaque suite de caractère qui répond au masque se retrouve dans
$0 ?


Oui. Voir <http://fr.php.net/manual/fr/function.preg-replace.php>.

et les apostrophes, ils servent à qqch ?


Il faut un caractère, n'importe lequel, pour indiquer le début et la fin
du masque, et le séparer des options. Habituellement on utilise "/" mais
"'" va tout aussi bien. Je ne trouve pas la référence dans la doc PHP,
peut-être parce qu'elle n'y est pas (il faut alors aller voir sur
<http://www.pcre.org> mais il n'est pas évident de le savoir, ce qui est
probablement la raison pour laquelle ton article n'a pas été refusé sous
le motif RTFM).

(je ne m'occupe pas des r qui ne devraient pas se trouver dans
$_POST)


ouais, c'est ce que je pensais aussi. on les trouve où ces caractères ?


Par exemple dans des fichiers MS-DOS ou Windows (séquence rn) ou dans
des fichiers Macintosh (r seul) lus en mode binaire. Quand tu lis un
fichier en mode texte ou le résultat d'un POST, PHP a le bon goût
d'uniformiser tout ça.

d'ailleurs, ça me fait penser qu'au départ j'avais bêtement essayé
str_replace("n","</p>n<p>",$_POST["texte"]), et ça n'a jamais
fonctionné. est ce que y a une raison ou est ce que c'est moi qui craque ?


Je ne vois pas pourquoi ça n'aurait pas fonctionné. La doc de
str_replace contient l'exemple suivant :

<cit.>
$message = str_replace ("n", "<BR>", "$message");
</cit.>

$texte = preg_replace("'[^n]'", "<p>$0</p>", $texte); [puis plus
loin : ] $texte = preg_replace("'^.*$'m", "<p>$0</p>", $texte);


ok. mais pourquoi on met une étoile dans le deuxième et pas dans le
premier ?


Parce que je me suis gourré dans le premier. Je n'ai testé aucun des
exemples que je t'ai donnés : félicitations pour y détecter les erreurs.

et "'.*'m", ça marche non ? (mais c'est juste parce que c'est
simple, c'est ça ?)


D'après la doc de l'option m (PCRE_MULTILINE), ça ne devrait pas marcher
sans ^ et $ mais il est vrai qu'il y a une contradiction entre cette doc
et celle de l'option s (PCRE_DOTALL). Encore une fois je n'ai pas testé,
donc essaye et tu nous diras.

[...] je suis pas sur d'avoir bien
compris l'intérêt du m, à part que le ^ et le $ ne sont plus des
fin-début de ligne :)


Au contraire ! Ils deviennent respectivement début et fin de ligne au
lieu de début et fin de texte.

$texte = preg_replace("'^[^<]*$'m", "<p>$0</p>", $texte);


juste pour savoir si j'ai bien compris : ici, le * s'applique à "pas de
<" ?


Oui, exactement.

$texte = preg_replace("'^[s]*([^<s]*)[s]*$'m", "<p>$1</p>",
$texte);


alors ici, le $1 est mis pour la classe du milieu ? le $0 existe
toujours, égal au total de la ligne ?


Oui, et oui. RTFM. ;-)


Avatar
Will
Le 27/03/2005 01:29 (à peu de choses près), Olivier Miakinen a
intelligemment dit...
d'ailleurs, ça me fait penser qu'au départ j'avais bêtement essayé
str_replace("n","</p>n<p>",$_POST["texte"]), et ça n'a jamais
fonctionné. est ce que y a une raison ou est ce que c'est moi qui craque ?
Je ne vois pas pourquoi ça n'aurait pas fonctionné. La doc de

str_replace contient l'exemple suivant :


en effet, c'est moi qui dit n'imp. désolé. ceci dit, pour ne pas toucher
les balises, je suis obligé d'utiliser des regexp, donc au final je peux
pas utiliser str_replace.

Encore une fois je n'ai pas testé, donc essaye et tu nous diras.


bon, au cas où ça intéresserait qqun :
pour mon cas, il faut bien "'^[^<].+$'m" . j'ai à peu près tout essayé
:), et il n'y a que cela qui fonctionne correctement (en particulier,
'[^<].+' n'évite pas les balises...)

Oui, et oui. RTFM. ;-)


désolé. :)

bon, sinon, j'ai un dernier petit problème : je me retrouve quand je
rentre ffffffffffffffffn avec en sortie <p>ffffffffffffffffn</p>n :
quand je rentre qch avec un retour à la ligne, je me retrouve avec, dans
mon source html, un retour à la ligne dont je ne veux pas avant </p>. je
ne sais pas trop comment l'enlever...

--
Will


Avatar
Olivier Miakinen

[...] "'^[^<].+$'m"

bon, sinon, j'ai un dernier petit problème : je me retrouve quand je
rentre ffffffffffffffffn avec en sortie <p>ffffffffffffffffn</p>n :
quand je rentre qch avec un retour à la ligne, je me retrouve avec, dans
mon source html, un retour à la ligne dont je ne veux pas avant </p>.


C'est bizarre. Cela peut être soit un bug de PHP lui-même, soit un bug
de la doc. Par exemple, la doc de l'option D est fausse en français (en
tout cas l'explication française ne veut rien dire, alors que cela
semble clair en anglais).

Ou alors, c'est que $0 inclut le caractère de fin de ligne, même si le
'$' dans la chaîne de recherche l'exclut.

je ne sais pas trop comment l'enlever...


"'^([^<].+)$'m" avec utilisation de $1 au lieu de $0 ?

--
Olivier Miakinen
Non, monsieur le juge, je vous le jure : jamais je n'ai cité
Bruxelles dans ma signature.

Avatar
Will
Le 29/03/2005 13:23 (à peu de choses près), Olivier Miakinen a
intelligemment dit...
quand je rentre qch avec un retour à la ligne, je me retrouve avec, dans
mon source html, un retour à la ligne dont je ne veux pas avant </p>.
C'est bizarre. Cela peut être soit un bug de PHP lui-même, soit un bug

de la doc. Par exemple, la doc de l'option D est fausse en français (en
tout cas l'explication française ne veut rien dire, alors que cela
semble clair en anglais).


en fait, c'est un r. je sais pas pourquoi c'est là, mais bon... enfin
voilà, j'ai réussi à l'enlever du coup. merci pour tout.

--
Will