Discussion:
Expression reguliere: proteger les cara cteres speciaux
(trop ancien pour répondre)
DublinFrench
2009-10-05 08:27:50 UTC
Permalink
Salut

Je travaille avec preg_replace, mes tests vont bien et je voudrais
généraliser la procédure. Or, j'ai remarqué qu'une variable pouvait
contenir des caractères embêtants comme * . ou autres, et donc gêner le
bon déroulement de la procédure.

$chaine =
preg_replace('|(<a[^>]+>)(.*)('.$keyword.')(.*)(</a[^>]*>)|Ui', '$3',
$content);

Comment protéger $keyword avant le preg_replace ? Y a t il l'équivalent
d'un htmlentities pour les expression régulières ?

Merci :)

DF
Mickael Wolff
2009-10-05 10:16:11 UTC
Permalink
Post by DublinFrench
Comment protéger $keyword avant le preg_replace ? Y a t il l'équivalent
d'un htmlentities pour les expression régulières ?
preg_escape
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Olivier Miakinen
2009-10-05 10:16:11 UTC
Permalink
[Diapublication avec fr.comp.lang.regexp et retour dans fr.comp.lang.php]

Bonjour,
Post by DublinFrench
Je travaille avec preg_replace, mes tests vont bien et je voudrais
généraliser la procédure. Or, j'ai remarqué qu'une variable pouvait
contenir des caractères embêtants comme * . ou autres, et donc gêner le
bon déroulement de la procédure.
Logique.
Post by DublinFrench
$chaine =
preg_replace('|(<a[^>]+>)(.*)('.$keyword.')(.*)(</a[^>]*>)|Ui', '$3',
$content);
Comment protéger $keyword avant le preg_replace ? Y a t il l'équivalent
d'un htmlentities pour les expression régulières ?
Il n'existe aucune fonction toute prête à ma connaissance, mais elle
n'est pas très difficile à écrire.

Les caractères à protéger sont en premier lieu les métacaractères (ceux
qui ont un effet spécial en dehors des classes de caractères, donc pas
« ] » ni « - »). En principe il faut aussi protéger le caractère qui te
sert de délimiteur de début et de fin d'expression rationnelle, mais vu
que tu as choisi « | » il fait déjà partie de la liste des métacarac-
tères (sauf que du coup tu ne dois pas pouvoir écrire d'alternative dans
tes regexp).

Liste des métacaractères à protéger : « \^$.[|()?*+{ ». Bizarrement, la
page <http://fr2.php.net/manual/fr/regexp.reference.meta.php> y met
aussi les caractères « ] » et « } » ; pourtant il est bien dit que ce
n'est pas le cas, dans les pages suivantes :
<http://fr2.php.net/manual/en/regexp.reference.squarebrackets.php>
<http://fr2.php.net/manual/en/regexp.reference.repetition.php>
(ici j'ai mis les pages en anglais, car dans la traduction française
ils ont fait le contresens de traduire « not special » par « sans
signification » au lieu de « non spécial »).

La protection de ces caractères dans $keyword se fera en les faisant
précéder d'un « \ », donc un truc du genre :
$escaped_keyword = preg_replace('/[...]/', '\\$0', $keyword);
(n'oublions pas que le « \ » est aussi un caractère spécial dans
l'écriture des chaînes de caractères, il faut donc le protéger aussi).

Parmi les caractères de « \^$.[|()?*+{ », seuls deux peuvent être
des métacaractères dans une classe [...] : le caractère « ^ », mais
seulement s'il est placé au début ; le caractère « \ » qu'il faut donc
non seulement doubler (spécial dans [...]) mais quadrupler (spécial
dans l'écriture d'une chaîne de caractères).

Sauf erreur de ma part, on arrive donc à :
$escaped_keyword =
preg_replace('/[\\\\^$.[|()?*+{]/', '\\$0', $keyword);
... et il te suffit d'utiliser $escaped_keyword là où tu utilisais
$keyword précédemment.

Cordialement,
--
Olivier Miakinen
Mickael Wolff
2009-10-05 12:46:47 UTC
Permalink
Post by Olivier Miakinen
[Diapublication avec fr.comp.lang.regexp et retour dans fr.comp.lang.php]
Bonjour,
Post by DublinFrench
Je travaille avec preg_replace, mes tests vont bien et je voudrais
généraliser la procédure. Or, j'ai remarqué qu'une variable pouvait
contenir des caractères embêtants comme * . ou autres, et donc gêner le
bon déroulement de la procédure.
Logique.
Post by DublinFrench
$chaine =
preg_replace('|(<a[^>]+>)(.*)('.$keyword.')(.*)(</a[^>]*>)|Ui', '$3',
$content);
Comment protéger $keyword avant le preg_replace ? Y a t il l'équivalent
d'un htmlentities pour les expression régulières ?
Il n'existe aucune fonction toute prête à ma connaissance, mais elle
n'est pas très difficile à écrire.
preg_quote existe (et désolé pour le preg_escape de mon précédent
message)
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Olivier Miakinen
2009-10-05 13:49:25 UTC
Permalink
Post by Mickael Wolff
Post by Olivier Miakinen
Il n'existe aucune fonction toute prête à ma connaissance, mais elle
n'est pas très difficile à écrire.
preg_quote existe
Et qui croyais tout connaître des PCRE dans PHP ! En plus, elle est
beaucoup plus générique que mon bout de code puisqu'elle traite aussi
le cas du délimiteur, quel qu'il soit.

En retournant lire la doc, je m'aperçois qu'il y a encore une autre
fonction que je ne connaissais pas (mais celle-ci est beaucoup plus
récente, >= 5.3.0) : preg_filter().
Post by Mickael Wolff
(et désolé pour le preg_escape de mon précédent message)
Pas de mal. J'ai cru que c'était une fonction perso dont tu avais
oublié qu'elle n'était pas standard, car on trouve quelques fonctions
preg_escape en cherchant sur la toile.

Merci en tout cas !

Cordialement,
--
Olivier Miakinen
DublinFrench
2009-10-05 14:46:42 UTC
Permalink
Post by Olivier Miakinen
Et qui croyais tout connaître des PCRE dans PHP !
Nous sommes tous perpétuellement en phase d'apprentissage. Celui qui dit
le contraire est d'une totale mauvaise fois :)
Post by Olivier Miakinen
Post by Olivier Miakinen
= 5.3.0) : preg_filter().
preg_quote
Merci a vous deux :)

:)

@++

DF

Continuer la lecture sur narkive:
Loading...