comment remplacer une chaine entre 2 caracteres

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : comment remplacer une chaine entre 2 caracteres

par gros_debutant » 19 oct. 2008, 17:22

un grand merci encore une fois!
j'ai bien appris aujourd'hui grâce à toi!
et donc je confirme que ça marche bien

après renseignements, il y a donc les captures "gloutonnes" et tout un tas d'autres "options".
je vais pouvoir m'amuser avec ça :D

je vais aussi regarder avec les strpos mais ça me semble plus difficile alors que tu prétends le contraire :shock:
je ne clos donc pas tout de suite mon topic, comme ça au cas où... :oops: :wink:

une dernière question, dans mon cas à quoi aurait bien pu me servir un preg_match_all par exemple? c'est pour apprendre avec une idée de ce que je pourrais regarder.

par Ryle » 19 oct. 2008, 16:50

Tout à fait, le masque que tu utilisais était beaucoup trop restreint (il aurait fallu que ta chaine commence par µ, se termine par @, et qu'il n'y ait qu'une minuscule entre les deux pour qu'elle fonctionne :))

Pour répondre à ta question effectivement, il n'est pas utile de remplacer ta parenthèse par un µ pour la retrouver avec l'expression régulière. Faut juste faire attention que les parenthèse ont une signification particulière en expreg (elle capture ce qu'elles entourrent pour te permettre de le réutiliser) et qu'il faut donc spécifier que tu cherches bien le caractère "(" et non pas que tu essayes de capturer une partie de la chaine. Il suffit juste pour cela de mettre un antislash devant :)

Maintenant, il faut savoir que les expressions régulières sont "gourmandes". C'est à dire qu'elle ne vont pas se contenter d'un encas s'il y a tout un repas possible. Hors dans ta chaine, le masque µ.*@ s'applique effectivement cette partie là :
je suis un débutant µmais je me soigne@ bientôt je serais un expert µet je soignerais les autres@
mais également à celle-ci :
je suis un débutant µmais je me soigne@ bientôt je serais un expert µet je soignerais les autres@
Et comme tu le devines, l'expression régulière va chercher la plus grande chaine :)

Pour éviter cela on utilise des options, c'est à dire un complément d'infos au masque. Un "i" ("ignore case") va par exemple indiquer qu'on souhaite ignorer la casse des lettres. Dans notre cas, c'est l'option "U" ("Ungreedy") qui va nous interesser, dans ce sens où elle retire le caractère gourmand de l'expression. Ton masque devient alors : "#µ.*@#U"

par gros_debutant » 19 oct. 2008, 16:11

un grand merci pour le temps que tu as pris pour m'expliquer!

je commence par les regex étant donné que j'ai planché dessus mais la solution en strpos je la regarderai aussi!
donc si j'ai bien compris ma principale erreur avec les regex(j'ai bien dit principale :lol: ) vient du fait que mes recherches étaient limitées par rapport à ce que je cherchais.
Mais pour les ^µ et @$ le fait est que j'ai des listes avec des chaines comportant des parenthèses et des données à l'intérieur puis des sauts de paragraphes.
Voulant supprimer les données, j'ai d'abord transformer les '(' en 'µ' puis les sauts de paragraphe en @ (on ne retrouve jamais ces symboles dans mes listes). Je me disais que ainsi, il suffirai de supprimer ce que ces symboles entourent avant de supprimer les parenthèses.
Est ce que de cette façon on ne peut pas non plus considérer que mes chaines commencent et finissent par ses symboles?
Ce que j'ai du mal à comprendre alors, c'est l'utilité d'indiquer par quoi commence notre chaine si ce n'est pas pour ce genre de cas :? mais bon, ça j'essayerai de voir par moi-même :wink:

donc ok, j'ai juste ajouté un 'dièse #' à la fin de ton expression (un petit oubli) mais ça me supprime tout sauf le début et pas seulement ce qu'entourent mes 'µ' et '@' donc ici dans la chaine 'je suis un débutant µmais je me soigne@ bientôt je serais un expert µet je soignerais les autres@' ça me garde seulement 'je suis un débutant'.

c'est à la suite que va servir le preg_match_all?

par Ryle » 19 oct. 2008, 14:40

Alors déjà une solution simple, sans utiliser les expressions régulières, tu peux à l'aide de la fonction strpos() connaitre la position d'un caractère dans une chaine. En utilisant la fonction substr() tu peux dès lors couper ta chaine en allant de 0 à la position du caractères µ, puis du caractères @ jusqu'à la fin de ta chaine. Il te suffit ensuite de concaténer les deux pour obtenir ce que tu souhaites :)

Ca c'était pour la partie facile, sans prise de tête, maintenant on va voir ton expression régulière : "#^µ[a-z]@$#" :)

Alors déjà, ^ et $ désignent respectivement le début et la fin de ta chaine. En gros si ton masque est "^a" cela veut dire que tu cherches un "a" en tout début de chaine et pas ceux qui pourraient se trouver plus loin. Hors dans ton cas, ta chaine ne commence pas nécessairement par "µ" et ne se termine pas non plus forcément par "@". Tu cherches ce modèle peut importe l'endroit où il se trouve dans ta chaine. Donc on vire :)

Deuxième point, [a-z], correspond n'importe quelle lettre comprise entre "a" et "z". Mais si ta chaine contient un espace, il n'est pas pris en compte ici. Pas plus s'il contient une lettre majuscule, un chiffre, un trait d'union ou de la ponctuation... Donc option a, tu listes l'ensemble des caractères autorisés [a-zA-Z0-9,-....] ou option b, tu te moque de savoir ce qu'il y a entre µ et @ et tu veux juste que ça dégage. Tu peux alors utiliser le point "." qui désigne n'importe quel caractère (majuscule, minuscule, numérique, ponctuation, ...)

Troisième point, que tu écrives "[a-z]" ou ".", cela représente un caractère et un seul. Donc dès qu'il y en a plus d'un, ton expression ne correspond plus. Il faut donc préciser le nombre d'occurence, ex : [a-z]{2} pour 2 lettres minuscules. [a-z]{1,3} pour une à 3 lettres, etc. Maintenant on peut aussi utiliser les symboles ? + et * pour indiquer "0 ou 1", "1 ou n" et "0 ou n" (qui est ce qui va nous interesser dans ce cas ci, à savoir qu'il y ait un caractère ou 200, on dégage tout ce qu'il y a entre)

Ton expression devrait donc ressembler à : $a_remplacer="#µ.*@";

Essaye déjà comme ça, et on ira voir ensuite du côté des options et de preg_match_all pour que le résultat corresponde bien à ce que tu attends ;)

comment remplacer une chaine entre 2 caracteres

par gros_debutant » 19 oct. 2008, 13:53

bonjour.

après avoir débuté les regex je me trouve confronté à un problème d'une telle simplicité (du moins je pense) que j'en ai honte de ne pas pouvoir le résoudre!

voila: je cherche à supprimer ce qui se trouve entre deux caractères précis, genre 'µ' et '@'.
J'ai cherché sur internet, sur des tutoriaux, sur votre forum etc et j'ai bien trouvé les preg_replace et autres mais sans parvenir à faire fonctionner le bidule!

pourriez vous m'aider svp? voila ce que je veux: supprimer par exemple dans les chaines suivantes , les sous-chaines comprises entre 'µ' et '@':

$chaine=je suis un débutant µmais je me soigne@ bientôt je serais un expert µet je soignerais les autres@

entre autres j'ai essayé le code suivant qui me semblait le plus simple:
<?php 
$chaine='je suis un débutant µmais je me soigne@ bientôt je serais un expert µet je soignerais les autres@';
$a_remplacer="#^µ[a-z]@$#";
$remplacement='';
$chaine_modifiee=preg_replace($a_remplacer,$remplacement,$chaine);
echo $chaine_modifiee;
?>
merci d'avance :oops: