Remplacer un bout d'une chaine de caractère compris entre 2 mots

Signaler
Messages postés
404
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008
-
cs_mathmax
Messages postés
404
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008
-
Bonjour,
Je cherche comment remplacer un bout d'une chaine de caractères compris entre 2 mots par une autre chaine de caractères. Par exemple si j'ai la chaine de caractère suivante :
fdhkj ghkf ghhg kdfjhg kjfhkj hjkf hjk début bout de chaine à remplacer fin g fdhgdkyguidgyufidgy iudfygui
je voudrais la remplacer par :
fdhkj ghkf ghhg kdfjhg kjfhkj hjkf hjk début nouveau bout de chaine fin g fdhgdkyguidgyufidgy iudfygui

J'ai l'impression qu'il va falloir que j'utilise la classe regex, mais je ne vois pas comment...

Pourriez vous m'éclairer ?

Merci d'avance.


Mathmax

18 réponses

Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
32
déjà, il te faut trouver l'expression régulière qui va bien...

donc un truc du genre : (debut)(.*)(fin) devrait faire l'affaire...

Donc tu pourras avoir un bout de code comme celui-ci :


public
string RemplaceChaineEntre(
string orig,
string debut,
string fin,
string remplacement) {

string pattern =
string.Format(
"({0})(.*)({1})", debut, fin);
Regex regex =
new Regex(pattern);

return regex.Replace(orig,
"$1" + remplacement +
"$3");
}

j'ai pas testé... mais l'idée est là.

Sébastien FERRAND
[MVP C#]
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
32
ooops... petite erreur :


public
string RemplaceChaineEntre(
string orig,
string debut,
string fin,
string remplacement) {

string pattern =
string.Format(
"({0})(.*)({1})", debut, fin);
Regex regex =
new Regex(pattern, RegexOptions.Singleline);

return regex.Replace(orig,
"$1" + remplacement +
"$3");
}

ca fonctionnera mieux avec le Singleline

Sébastien FERRAND
[MVP C#]
Messages postés
404
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008

Il y deux trucs que je ne comprends pas dans ton code :

tout d'abord que signifie :
string pattern = string.Format("({0})(.*)({1})", debut, fin);
plus précisement, je ne comprends pas ce que signifie : "({0})(.*)({1})".

Plus généralement, j'ai toujours du mal à trouver ce que sont les paramètres des propriétés. Sur msdn, je ne trouve pas souvent ce que je cherche. aurais-tu une adresse qui liste les propriétés, méthodes, classes ? Ici c'est format qui me pose problème.

Merci pour ton aide


Mathmax
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
32
Ok...
en fait la méthode Format permet de "remplir" les espaces que tu laisses avec les {0}...

http://msdn.microsoft.com/library/fre/default.asp?url=/library/FRE/cpref/html/frlrfSystemStringClassFormatTopic.asp

et pis la msdn, c'est pas si dur

Sébastien FERRAND
[MVP C#]
Messages postés
404
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008

Excuse moi, j'ai un peu raté mon coup...
Je ne comprends pas trop ce que tu veux dire par : "remplir" les espaces que tu laisses avec les {0}...
Sinon il n'existe pas des solutions du coté de la méthode read ? Lire une chaine de carctère jusqu'à un certain mot (dans notre cas début), la relire à partir d'un autre mot (dans notre cas fin) et inserer entre les 2 notre chaine de caractère de remplacement. On stockerais le tout dans un variable string. Est-il possible de lire un chaine de caractères jusqu'à un certain mot/ou à partir d'un certain mot?


Mathmax
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
32
Tu exagères concernant la méthode Format de la classe String, je t'ai donné le lien vers la msdn tu pourrais lire

concernant la lecture séquentielle de la chaine... oui c'est faisable mais super long... alors que l'expression régulière est très rapide pour ce genre de travail.

Sébastien FERRAND
[MVP C#]
Messages postés
404
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008

Après relecture de ton lien et de celui -ci :http://msdn.microsoft.com/library/fre/default.asp?url=/library/FRE/cpref/html/frlrfsystemstringclassformattopic1.asp, j'avoue que je n'ai toujours pas tout compris... désolé, jai un peu du mal...

J'ai cependant éxécuté ton bout de code (que j'ai un peu modifiécar Visual Studio n'appréçie pas quand je le met directement dans static
void Main(
string[] args) (au passage je précise que l'ai mis ça dans une console application)) :



string s =
"";



string orig =
" vhjhdfjghkjdg hfkjdhkj debut df sjhfjdg hfgdhjhgj fin fshdu f dshgjj";



string debut =
"debut";



string fin =
"fin";



string remplacement =
"remplacement";



string pattern =
string.Format(
"({0})(.*)({1})", debut, fin);



Regex regex =
new
Regex(pattern,
RegexOptions.Singleline);


s = regex.Replace(orig,
"$1" + remplacement +
"$3");



Console.Out.WriteLine(s);

En
débugant, j'ai tout de même compris quelques petites chôses (enfin j'éspère...)
Visiblement : le {0} est remplacé par la chaine placée en deuxièmeparamètre de format
le {1}est remplacé par la chaine placée en troisième paramètre de format
puis "$1","$2" et "$3" doivent renvoyer aux chaines "debut", "fin" et à ce qu'il y a entre les deux
le (.*) doit représenter la chaine de caractère (peu importe sa valeur) compris entre debut et fin. D'habitude on met une * non ? Là j'ai essayé mais à priori ça ne marche pas.




Mathmax
Messages postés
9
Date d'inscription
lundi 6 septembre 2004
Statut
Membre
Dernière intervention
4 décembre 2005

Yop Yop

Hmm je pige pas pourquoi utiliser un "Format" plutôt que de faire ca :

string myFullString = "fdhkj ghkf ghhg kdfjhg kjfhkj hjkf hjk début bout de chaine à remplacer fin g fdhgdkyguidgyufidgy iudfygui";

string myFirstString = "début";

string myLastString = "fin";

string myNewString = " nouveau bout de chaine ";

Regex myRegex =
new Regex(myFirstString + ".*" + myLastString);

string myFinalString = myRegex.Replace(myFullString, myFirstString + myNewString + myLastString);


Ika
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
32
pourquoi utiliser format... simplement parce que c'est plus simple que de faire ce que tu nous montres.

et puis, la méthode Format est optimisée pour ce genre d'opération.

Sébastien FERRAND
[MVP C#]
Messages postés
9
Date d'inscription
lundi 6 septembre 2004
Statut
Membre
Dernière intervention
4 décembre 2005

Comment ça ? je fais une opération de moins pourtant. Tu veux dire que le "Format" optimise l'expression régulière ? (je sais je suis lourd, j'veux juste comprendre mon erreur :D)
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
32
bon... en gros voici le détail du code :

public string RemplaceChaineEntre(string orig, string debut, string fin, string remplacement) {
string pattern = string.Format("({0})(.*)({1})", debut, fin);
Regex regex = new Regex(pattern, RegexOptions.Singleline);

return regex.Replace(orig, "$1" + remplacement + "$3");
}

la ligne : string pattern = string.Format("({0})(.*)({1})", debut, fin);

construit une expression régulière du type : (début)(.*)(fin), le string.Format permet d'optimiser la création de la chaine.

ensuite, j'instancie l'objet regex qui va permettre le remplacement.
et pour terminer, j'exécute l'expression sur la chaine d'entrée.

j'aurais pu l'écrire en une ligne... mais niveau compréhension, ce n'est pas le top :

public string RemplaceChaineEntre(string orig, string debut, string fin, string remplacement) {
return (new Regex(string.Format("({0})(.*)({1})", debut, fin),
RegexOptions.Singleline)).Replace(orig, "$1" + remplacement + "$3");
}

Sébastien FERRAND

[MVP C#]
Messages postés
9
Date d'inscription
lundi 6 septembre 2004
Statut
Membre
Dernière intervention
4 décembre 2005

Ahh oki doki :)

Mici :)
Messages postés
404
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008

Ok merci pour les conseils sebmafate . Il y a plus qu'un truc que je ne comprends pas (enfin je crois). Je n'arrive pas à comprendre où est-ce qu'on insère des bouts de code comme le tient ( c'est à dire des trucs commençant par public, private,...), par exemple dans une console application (j'en suis encore là... il me reste beaucoup à apprendre). Ma question doit te paraitre un peu ridicule, mais je n'ai toutjours pas réussi à le placer correctement sans que ça génère d'erreur..


Mathmax
Messages postés
404
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008

Encore un autre petit problème :si j'ai une chaine de caractères du style :

vhjhdfjghkjdg hfkjdhkj debut df sjhfjdg hfgdhjhgj fin fshdu f dshgjj fin

Comment choisir si l'on remplace le texte compris entre debut et le premier fin ou entre debut et le deuxième fin ?
Avec le code que tu m'as donné, ce qui est remplaçé est le texte compris entre debut et le deuxième fin.

Merci d'avance


Mathmax
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
32
tout à fait... j'ai oublié cette possibilité

public string RemplaceChaineEntre(string orig, string debut, string fin, string remplacement) {
string pattern = string.Format("({0})(.* ? )({1})"
, debut, fin);
Regex regex = new Regex(pattern, RegexOptions.Singleline);

return regex.Replace(orig, "$1" + remplacement + "$3");
}

il suffit d'ajouter le ? à l'endroit indiqué

Sébastien FERRAND
[MVP C#]
Messages postés
404
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008

Le point ? signifie que l'on prend la première occurence de fin ?
Et si maintenant j'ai 3 fin et que je veux prendre le deuxième comme limite pour la fin du bout remplaçé, comment faire ?


Mathmax
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
32
oui... ? c'est 0 ou 1 fois.

mais il n'existe pas de solution pour si tu veux le second.

Sébastien FERRAND
[MVP C#]
Messages postés
404
Date d'inscription
vendredi 28 octobre 2005
Statut
Membre
Dernière intervention
31 août 2008

C'est embettant car j'ai dans mon fichier plusieurs debut ... fin. Je voudrais remplacer chaque occurence par des strings que j'ai stockées dans un tableau. Voici un exemple qui illustre ce que je veux faire :

string[] t={"string_1","string_2",...,"string_n");
for (int i =0; i<=t.Length-1;i++)
{
remplacer le (i+1)ème texte compris entre debut et fin par t[i]
}

Y a t-il un moyen de faire cela ?

Mathmax