Quel pattern pour un preg_replace un peu particulier?

Nelly
Invité n'ayant pas de compte PHPfrance

28 août 2007, 23:11

Bonsoir,
J'ai un nouveau problème. J'ai une phrase du style

Code : Tout sélectionner

...A.....A.....A.....B.....A.....A.....B.....A.....A
(les points de suspension sont n'importe quoi sauf des A et B)
Je veux remplacer A par C mais uniquement ceux qui sont suivis par des B(et sans autre A entre)
Ca donnerait :

Code : Tout sélectionner

...A.....A.....C.....B.....A.....C.....B.....A.....A
Je ne vois pas quel pattern utiliser. Est ce que quelqu'un peut m'aider svp?

Eléphanteau du PHP | 11 Messages

28 août 2007, 23:40

Salut,
comme motif, je te propose : "`A(?=[^AB]*B)`".
Ca donne donc :
$text = preg_replace('`A(?=[^AB]*B)`', 'C', $text);
Si tu te demandes à quoi correspond la partie bizarre avec un point d'interrogation :p , va voir ce tuto (par exemple).

Invité
Invité n'ayant pas de compte PHPfrance

29 août 2007, 00:43

Ok merci bcp, ça fonctionne et je comprends mais pour simplifier, j'avais pris l'exemple de A B et C or ce sont en réalité des mots de plusieurs caractères. J'ai essayé de remplacer le [^AB] par [^(motA)(motB)] mais il exclue des qu'il y a une des lettre de motA ou de motB. Comment faire pour dire que c'est vraiment motA et motB que je ne veux pas?

Eléphanteau du PHP | 11 Messages

29 août 2007, 14:56

Ah ok, c'est vrai que ce serait trop facile sinon :roll:. (C'est ironique bien sûr.)
Tu peux utiliser ceci : "`motA(?=(?:[^m]|(?!motA))*motB)`". Ca me semble correct.

Invité
Invité n'ayant pas de compte PHPfrance

29 août 2007, 15:09

arg.... Je te remercie mais ce n'est toujours pas ça et c'est ma faute....Si j'ai bien compris, [^m] signifie qu'il ne faut pas de lettre m entre motA et motB or il peut très bien y avoir motC ou motD,...
Peux-tu encore m'aider s'il te plait?

Eléphanteau du PHP | 11 Messages

29 août 2007, 15:45

Non non, ce coup-ci c'est moi qui me suis planté ^^.
J'espère que ceci sera correct : "`motA(?=(?:[^m]|m(?!otA))*motB)`".
J'ai mis les 2 "m" en gras pour te dire qu'ils sont à remplacer par la première lettre de motA.

Invité
Invité n'ayant pas de compte PHPfrance

29 août 2007, 17:00

!!!!!! Merci beaucoup!! C'est vraiment parfait. Le petit hic c'est que je n'ai pas tout compris à ce motif mais je vais essayer de me replonger là dedans...

Eléphanteau du PHP | 11 Messages

29 août 2007, 18:01

Je vais essayer d'expliquer de façon brève.

Code : Tout sélectionner

`motA(?=(?:[^m]|m(?!otA))*motB)`
Le but est de trouver les occurence du motA suivi par le motB sans qu'il n'y ait le motA entre les 2.
On ne veut capturer que le motA, pas la suite donc pour vérifier que cette suite satisfait bien nos conditions, on doit utiliser une assertion.
L'assertion est composée de 2 parties : (?:[^m]|m(?!otA))* et motB.
La première partie désigne n'importe quelle suite de caractères ne contenant pas le motA. En effet, chaque caractère est différent de "m" ou alors c'est un "m" mais pas suivi de "otA" (assertion avant négative).
La 2e partie est assez triviale je pense ;).

Invité
Invité n'ayant pas de compte PHPfrance

29 août 2007, 18:15

Wouaouuuu! J'ai compris, merci encore!