par
Ripat » 08 janv. 2006, 09:49
Il n'y a pas d'erreur de syntaxe dans ta regex mais bien de logique. C'est assez curieux à première vue, mais normal. Un preg_replace repère d'abord toutes les occurrences d'un motif et ensuite seulement procède au remplacement.
Donc dans son travail de repérage des chaînes à remplacer, tu lui demandes de capturer, par exemple le mot
suis précédé et suivi par un espace.
Il va repérer:
je vers je aller sortir voila c\'est fini je suis suis je comme quoi...
Tu remarqueras que les autres
je, suis ne sont plus précédés par un espace! Ils ne seront donc pas repérés et remplacés.
Bon, comment faire alors? Comme toujours en regex, plusieurs possibilités:
- Utiliser l'assertion magique \b qui marque une séparation de mot (y compris la ponctuation) et qui ne consomme pas de caractères (important!):
$chaine = preg_replace('#\b(suis|je|aidez)\b#', null, $chaine);
// ou, pour gagner (un poil) en rapidité, retirer le caractère capturant des parenthèses.
$chaine = preg_replace('#\b(?:suis|je|aidez)\b#', null, $chaine);
- Le plus rapide (de 2 à 10 fois plus rapide selon la longueur du texte).
Faire plusieurs preg_replace plutôt qu'un seul:
$mots = array('#\bsuis\b#', '#\bje\b#', '#\baidez\b#');
$chaine = preg_replace($mots, null, $chaine);
Il n'y a pas d'erreur de syntaxe dans ta regex mais bien de logique. C'est assez curieux à première vue, mais normal. Un preg_replace repère d'abord toutes les occurrences d'un motif et ensuite seulement procède au remplacement.
Donc dans son travail de repérage des chaînes à remplacer, tu lui demandes de capturer, par exemple le mot [b]suis[/b] précédé et suivi par un espace.
Il va repérer:
[color=blue]je vers[u] je [/u]aller sortir voila c\'est fini[u] je [/u]suis[u] suis j[/u]e comme quoi...[/color]
Tu remarqueras que les autres [b]je, suis[/b] ne sont plus précédés par un espace! Ils ne seront donc pas repérés et remplacés.
Bon, comment faire alors? Comme toujours en regex, plusieurs possibilités:[list]
[*]Utiliser l'assertion magique [b]\b[/b] qui marque une séparation de mot (y compris la ponctuation) et qui ne consomme pas de caractères (important!):
[php]$chaine = preg_replace('#\b(suis|je|aidez)\b#', null, $chaine);
// ou, pour gagner (un poil) en rapidité, retirer le caractère capturant des parenthèses.
$chaine = preg_replace('#\b(?:suis|je|aidez)\b#', null, $chaine);[/php]
[*]Le plus rapide (de 2 à 10 fois plus rapide selon la longueur du texte).
Faire plusieurs preg_replace plutôt qu'un seul:
[php]$mots = array('#\bsuis\b#', '#\bje\b#', '#\baidez\b#');
$chaine = preg_replace($mots, null, $chaine);[/php][/list]