IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

remplacer n occurences dans une chaine de caractère.


Sujet :

C#

  1. #1
    maa
    maa est déconnecté
    Membre actif
    Avatar de maa
    Inscrit en
    Octobre 2005
    Messages
    672
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Octobre 2005
    Messages : 672
    Points : 288
    Points
    288
    Par défaut remplacer n occurences dans une chaine de caractère.
    Bonjour,

    Je cherche à implémenter en c# l'équivalent de la fonction Clipper suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
     STRTRAN()
     Recherche et remplace des caractères dans une chaîne de caractères ou un
     champ mémo
    ------------------------------------------------------------------------------
     Syntaxe
     
         STRTRAN(<cChaine>, <cCherche>,
            [<cRemplace>], [<nDebut>], [<nCompte>]) --> cNouvChaine
     
     Arguments
     
         <cChaine> est la chaîne de caractères ou le champ mémo à parcourir.
     
         <cCherche> est la séquence de caractères à trouver.
     
         <cRemplace> est la séquence de caractères devant remplacer
         <cCherche>. Si cet argument n'est pas spécifié, les occurrences trouvées
         sont remplacées par une chaîne vide ("").
     
         <nDebut> est la première occurrence à remplacer. Si cet argument est
         omis, la valeur par défaut est un.
     
         <nCompte> est le nombre d'occurrences à remplacer. Si cet argument
         n'est pas spécifié, la valeur par défaut est tout.
    Comment faire cela le plus efficacement possible. C'est une fonction qui va être appelée en série par SQL server sur plusieurs millions d'enregistrements. J'ai besoin qu'elle soit le plus efficace possible.

    Merci d'avance pour vos suggestions.

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 23
    Points : 18
    Points
    18
    Par défaut
    Salut !

    Simplement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    String SourceString = "0101";
    SourceString.Replace("0", "2");
    Donnera "2121".

    Sinon jette un œil sur les expressions régulière si tu veux rechercher des éléments plus complexe dans la string source.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 23
    Points : 18
    Points
    18
    Par défaut
    Pour ce qui est des autres paramètres regarde les methodes (SubString, IndexOf) disponibles sur une String.

    Tu à tout à disposition.

    GL

  4. #4
    maa
    maa est déconnecté
    Membre actif
    Avatar de maa
    Inscrit en
    Octobre 2005
    Messages
    672
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Octobre 2005
    Messages : 672
    Points : 288
    Points
    288
    Par défaut
    Je vois comment faire avec IndexOf + substring + replace. Mais je cherche la méthode la plus efficace possible.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 23
    Points : 18
    Points
    18
    Par défaut
    Ah le problème est sur la performance!

    Dans ce cas utilise la classe StringBuilder pour des opérations rapides.
    Car beaucoup de méthodes de la classe String utilisent des objets temporaires qui peuvent couter cher.

    Par contre String.IndexOf est une des méthodes les plus rapide. Par exemple utiliser IndexOf avec des liste de keyValue pour toutes les lettres est plus rapide que ToUpper ou ToLower.

    Il faut creuser un peu.

  6. #6
    maa
    maa est déconnecté
    Membre actif
    Avatar de maa
    Inscrit en
    Octobre 2005
    Messages
    672
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Octobre 2005
    Messages : 672
    Points : 288
    Points
    288
    Par défaut
    ok merci, j'ai opté pour ça. Un peut redondant, mais efficace je crois.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
            static string Replace(string cChaine, string cCherche, string cRemplace, int? nDebut, int? nCompte)
            {
                if (cRemplace == null)
                    cRemplace = string.Empty;
     
                bool lFirstParam = nDebut != null && nDebut != 1;
                bool lSecondParam = nCompte != null;
     
                if (nCompte == 0)
                    return cChaine;
     
                if (lFirstParam && lSecondParam)
                {
                    int j = -1;
                    for (int i = 0; i < nDebut; i++)
                    {
                        int j2 = cChaine.IndexOf(cCherche, j + 1);
                        if (j2 < j)
                            return cChaine;
                        j = j2;
                    }
                    int k = j - 1;
                    for (int i = 0; i < nCompte; i++)
                    {
                        int k2 = cChaine.IndexOf(cCherche, k + 1);
                        if (k2 < k)
                            return string.Concat(cChaine.Substring(0, j), cChaine.Substring(j).Replace(cCherche, cRemplace));
                        k = k2;
                    }
                    if (k > j)
                        k += cCherche.Length;
                    return string.Concat(cChaine.Substring(0, j), cChaine.Substring(j, k - j).Replace(cCherche, cRemplace), cChaine.Substring(k));
                }
                else if (lFirstParam)
                {
                    int j = -1;
                    for (int i = 0; i < nDebut; i++)
                    {
                        int j2 = cChaine.IndexOf(cCherche, j + 1);
                        if (j2 < j)
                            return cChaine;
                        j = j2;
                    }
                    return string.Concat(cChaine.Substring(0, j), cChaine.Substring(j).Replace(cCherche, cRemplace));
                }
                else if (lSecondParam)
                {
                    int k = -1;
                    for (int i = 0; i < nCompte; i++)
                    {
                        int k2 = cChaine.IndexOf(cCherche, k + 1);
                        if (k2 < k)
                            return cChaine.Replace(cCherche, cRemplace);
                        k = k2;
                    }
                    k += cCherche.Length;
                    return string.Concat(cChaine.Substring(0, k).Replace(cCherche, cRemplace), cChaine.Substring(k));
                }
                else
                    return cChaine.Replace(cCherche, cRemplace);
            }

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 23
    Points : 18
    Points
    18
    Par défaut
    Ouep, pas top niveau réutilisation du code mais çà semble efficace.

    Un seul petit commentaire, tu pourrais utiliser le polymorphisme plutôt que les type Nullable, c'est plus agréable à l'utilisation. Enfin seulement si c'est une méthode utiliser par des tiers.

    Bye

  8. #8
    maa
    maa est déconnecté
    Membre actif
    Avatar de maa
    Inscrit en
    Octobre 2005
    Messages
    672
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Octobre 2005
    Messages : 672
    Points : 288
    Points
    288
    Par défaut
    En fait je suis obligé d'utiliser le type object car un projet pour SQL Server n'accepte pas les type nullable en paramètre des fonctions portant l'attribut SqlFunction.

  9. #9
    Membre éclairé
    Inscrit en
    Octobre 2006
    Messages
    587
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Octobre 2006
    Messages : 587
    Points : 706
    Points
    706
    Par défaut
    Si tu peux refactorise ta méthode pour améliorer sa lisibilité ainsi que sa facilité de maintenance.

  10. #10
    maa
    maa est déconnecté
    Membre actif
    Avatar de maa
    Inscrit en
    Octobre 2005
    Messages
    672
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Octobre 2005
    Messages : 672
    Points : 288
    Points
    288
    Par défaut
    oui mais je perds en efficacité. Peux être pas beaucoup ? J'ai du mal à m'en rendre compte...

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 23
    Points : 18
    Points
    18
    Par défaut
    Tu pourrais utiliser les paramètres optionnels de c# :

    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
        public int Addition(String s, params int[] numbers) {
           int temp = 0;
           foreach( int i in numbers ) {
              temp += i;
              Console.WriteLine( s + i.ToString() );
           }
           return temp;
        }
    OU

    Avoir plusieurs signature pour ta méthode (c'est le plus propre) :

    static string Replace(string cChaine, string cCherche, string cRemplace)
    static string Replace(string cChaine, string cCherche, string cRemplace, int nDebut)
    static string Replace(string cChaine, string cCherche, string cRemplace, int nCompte)
    static string Replace(string cChaine, string cCherche, string cRemplace, int nDebut, int nCompte)

    Qui finissent tous par appeler la plus complète.

    OU

    Utiliser le Wrapper "Integer" plutot que le type de base "int". Car le passage d'un Integer se fait par référence donc peut être null.
    Sachant que la conversion Integer>int et int>Integer se fait automatiquement.

    static string Replace(string cChaine, string cCherche, string cRemplace, Integer nDebut, Integer nCompte)

    Voila!

  12. #12
    maa
    maa est déconnecté
    Membre actif
    Avatar de maa
    Inscrit en
    Octobre 2005
    Messages
    672
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Octobre 2005
    Messages : 672
    Points : 288
    Points
    288
    Par défaut
    Je ne peux pas avoir plusieurs ovlerload pour une méthode dans un projet SQL Server.
    Je ne souhaite pas appeler à chaque fois la méthode la plus complexe car je vais alors parfois concaténer des chaines vides ou faire des substring sur une longueur de 0 ce qui est du travail inutile...
    Pour le wrapper Integer, à quel namespace appartient t-il ? Je ne l'ai pas dans l'intellisens.

  13. #13
    Membre éclairé
    Inscrit en
    Octobre 2006
    Messages
    587
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Octobre 2006
    Messages : 587
    Points : 706
    Points
    706
    Par défaut
    Citation Envoyé par NoCxDev2 Voir le message
    Tu pourrais utiliser les paramètres optionnels de c#
    Euh les paramètres optionnels n'existent pas en C#.

    Citation Envoyé par maa Voir le message
    Pour le wrapper Integer, à quel namespace appartient t-il ? Je ne l'ai pas dans l'intellisens.
    On passe un entier via un SqlParameter de type SqlType.Integer

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 23
    Points : 18
    Points
    18
    Par défaut
    Euh les paramètres optionnels n'existent pas en C#.
    As-tu pris la peine de regarder mon exemple ?

    Cela existe, et permet d'avoir un comportement se rapprochant des paramètres optionnels.

    Bye

Discussions similaires

  1. Réponses: 9
    Dernier message: 23/12/2013, 16h40
  2. Remplacer un élément dans une chaine de caractères
    Par mauyebo dans le forum Langage
    Réponses: 1
    Dernier message: 05/09/2008, 21h03
  3. Réponses: 2
    Dernier message: 14/11/2007, 16h43
  4. Réponses: 4
    Dernier message: 09/09/2006, 10h18
  5. remplacer les cotes dans une chaine de caractère
    Par zut94 dans le forum Langage
    Réponses: 3
    Dernier message: 30/08/2006, 17h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo