OVH Cloud OVH Cloud

Expression reguliere

15 réponses
Avatar
Benjamin
Bonjour,

J'utilise preg_replace dans un de mes scripts php pour remplacer
l'expression ''' (triple guillemet) par la balise html <b>

Exemple :
Bonjour je m'appelle ''' john ''' et j'aime le php
Devient
Bonjour je m'appelle <b> john </b> et j'aime le php

J'ai écris la ligne suivant :
$text = preg_replace( "/\'\'\'([^\'\'\']*)\'\'\'/","<b>\\1</b>",$text);

Cela fonctione bien, excepté dans les cas suivant :
Bonjour je m'appelle ''' l'anata ''' et j'aime le php

Un pro des expression régulière pourrait-il m'aider ?

Merci
Ben

10 réponses

1 2
Avatar
Paul Delannoy
Benjamin a écrit:
Bonjour,

J'utilise preg_replace dans un de mes scripts php pour remplacer
l'expression ''' (triple guillemet) par la balise html <b>

Exemple :
Bonjour je m'appelle ''' john ''' et j'aime le php
Devient
Bonjour je m'appelle <b> john </b> et j'aime le php

J'ai écris la ligne suivant :
$text = preg_replace( "/'''([^''']*)'''/","<b>1</b>",$text);

Cela fonctione bien, excepté dans les cas suivant :
Bonjour je m'appelle ''' l'anata ''' et j'aime le php


Essaye donc :
$un=strpos("'''",$text);
$deux=strpos("'''",$text,$un)
$text=substr($text,0,$un)."<b>".substr($text,$un+3,$deux-$un-3)."</b>".substr($text,$deux+3);

et tu peux même rappeler ce schéma jusqu'à ce que le calcule de $un
renvoie false.

Pas testé, mais... j'y crois ! J'eqça.

Avatar
Olivier Miakinen

J'utilise preg_replace dans un de mes scripts php pour remplacer
l'expression ''' (triple guillemet) par la balise html <b>

Exemple :
Bonjour je m'appelle ''' john ''' et j'aime le php
Devient
Bonjour je m'appelle <b> john </b> et j'aime le php

J'ai écris la ligne suivant :
$text = preg_replace( "/'''([^''']*)'''/","<b>1</b>",$text);


Tiens ? Je suis surpris que cela fonctionne sur ton exemple, car
normalement les antislashs ne devraient pas être là (¹) :
$text = preg_replace( "/'''([^''']*)'''/", "<b>1</b>", $text);

J'ai vérifié, cela fonctionne, mais grâce à preg_replace() lui-même.

Cela fonctione bien, excepté dans les cas suivant :
Bonjour je m'appelle ''' l'anata ''' et j'aime le php


Bon, il est assez trivial, en lisant la doc (²), de voir que la syntaxe
[^'''] est strictement équivalente à [^''''''''''] ou à [^']. Du coup,
il est normal que ça bloque sur une apostrophe seule.

Mais en lisant une autre partie de la doc (³) tu peux trouver l'option U
qui inverse la gourmandise des expressions rationnelles, ce qui fait
exactement ce que tu veux :
$text = preg_replace( "/'''(.*)'''/U", "<b>1</b>", $text);

(¹)
http://www.php.net/manual/fr/language.types.string.php#language.types.string.syntax.double
(²) http://www.php.net/manual/fr/reference.pcre.pattern.syntax.php
(³) http://www.php.net/manual/fr/reference.pcre.pattern.modifiers.php

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

Avatar
Vincent Lascaux
Mais en lisant une autre partie de la doc (³) tu peux trouver l'option U
qui inverse la gourmandise des expressions rationnelles, ce qui fait
exactement ce que tu veux :
$text = preg_replace( "/'''(.*)'''/U", "<b>1</b>", $text);


Oui, mais si je ne m'abuse '''foo''' bla bla '''bar''' donnerait <b>foo'''
bla bla '''bar</b>
$text = preg_replace("/'''(([^']|'[^']|''[^'])*)'''/", "<b>1</b>", $text);
traite bien le cas où il y a plusieurs blocs à mettre en gras

--
Vincent

Avatar
Olivier Miakinen

Mais en lisant une autre partie de la doc (³) tu peux trouver l'option U
qui inverse la gourmandise des expressions rationnelles, ce qui fait
exactement ce que tu veux :
$text = preg_replace( "/'''(.*)'''/U", "<b>1</b>", $text);


Oui, mais si je ne m'abuse '''foo''' bla bla '''bar''' donnerait <b>foo'''
bla bla '''bar</b>


Eh bien tu t'abuses. Le comportement que tu décris est celui par défaut,
c'est-à-dire *sans* l'option U. Avec l'option U cela marche finement.

$text = preg_replace("/'''(([^']|'[^']|''[^'])*)'''/", "<b>1</b>", $text);
traite bien le cas où il y a plusieurs blocs à mettre en gras


Hum... sans doute, mais je trouve ma version légèrement plus lisible...

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


Avatar
CrazyCat
Olivier Miakinen wrote:
Bon, il est assez trivial, en lisant la doc (²), de voir que la syntaxe
[^'''] est strictement équivalente à [^''''''''''] ou à [^']. Du coup,
il est normal que ça bloque sur une apostrophe seule.

Mais en lisant une autre partie de la doc (³) tu peux trouver l'option U
qui inverse la gourmandise des expressions rationnelles, ce qui fait
exactement ce que tu veux :
$text = preg_replace( "/'''(.*)'''/U", "<b>1</b>", $text);


Bon, la bonne nouvelle c'est que j'ai appris quelque chose de fort
utile, je ne voyais pas la solution du problème de Benjamin.

Maintenant, pour un soucis de lisibilité, je préconiserais plutôt:
$text = preg_replace( "/'{3}(.*)'{3}/U", "<b>1</b>", $text);

Ce n'est pas grand chose, mais si tu veux remplacer ''' par <b> et ''
par <i>, tu risques vite de te perdre dans tes expressions régulières
(c'est en fait le principe de spip avec des [ ])

--
Découvrez Original War: http://www.original-war.org
Humour: http://www.chatfou.com
Tchattez en liberté: http://www.crazy-irc.net

Avatar
Olivier Miakinen

$text = preg_replace( "/'''(.*)'''/U", "<b>1</b>", $text);


Maintenant, pour un souci de lisibilité, je préconiserais plutôt:
$text = preg_replace( "/'{3}(.*)'{3}/U", "<b>1</b>", $text);


Moui. Même si je suis d'accord que "[^a-z0-9|~&@=]{3}" est un peu plus
lisible que "[^a-z0-9|~&@=][^a-z0-9|~&@=][^a-z0-9|~&@=]", je trouve
"'{3}" beaucoup moins lisible que "'''".

C'est une question d'habitude, peut-être.

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


Avatar
P'tit Marcel
Olivier Miakinen wrote:

$text = preg_replace( "/'''([^''']*)'''/","<b>1</b>",$text);


Tiens ? Je suis surpris que cela fonctionne sur ton exemple, car
normalement les antislashs ne devraient pas être là


Ce n'est pas "qu'ils ne devraient pas être là", c'est amha juste qu'ils
sont inutiles...


Avatar
Olivier Miakinen
Le 16/05/2005 23:42, P'tit Marcel m'a répondu :

$text = preg_replace( "/'''([^''']*)'''/","<b>1</b>",$text);


Tiens ? Je suis surpris que cela fonctionne sur ton exemple, car
normalement les antislashs ne devraient pas être là


Ce n'est pas "qu'ils ne devraient pas être là", c'est amha juste qu'ils
sont inutiles...


Non, je persiste et je signe.

<http://www.php.net/manual/fr/language.types.string.php#language.types.string.syntax.double>
Si vous essayez d'utiliser l'anti-slash sur n'importe quelle autre
séquence, l'anti-slash sera affiché dans votre chaîne.
</>

D'ailleurs tu peux faire le test : echo "'''" n'affichera pas la même
chose que echo "'''". Il se trouve que la fonction preg_replace
ignore les antislashs en trop, mais sinon cela ferait une différence.

--
Olivier Miakinen



Avatar
cleo
Il se trouve que la fonction preg_replace
ignore les antislashs en trop, mais sinon cela ferait une différence.

Salut,


preg_replace n'ignore rien, le est le caractère d'échappement pour
l'expression regulière également.
Le plus comique c'est quand, dans votre expression regulière, vous
recherchez un ...

Amicalement
--
Cléo

Avatar
P'tit Marcel
Olivier Miakinen wrote:

Le 16/05/2005 23:42, P'tit Marcel m'a répondu :

$text = preg_replace( "/'''([^''']*)'''/","<b>1</b>",$text);


Tiens ? Je suis surpris que cela fonctionne sur ton exemple, car
normalement les antislashs ne devraient pas être là


Ce n'est pas "qu'ils ne devraient pas être là", c'est amha juste qu'ils
sont inutiles...


Non, je persiste et je signe.

Il se trouve que la fonction preg_replace
ignore les antislashs en trop, mais sinon cela ferait une différence.


Le cas général est : il ne faut pas échapper les apostrophes dans une
chaîne délimitée par des guillemets.
Le cas particulier : cela ne porte pas à conséquence si la chaîne sert
de masque pour une fonction pre_xxxx


Nous sommes donc bien d'accord : dans ce masque, les antislashes sont
inutiles mais ils n'empêchent pas le bon fonctionnement du preg_match.

ou j'ai pas bon ?




1 2