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 :

Suppression des caractères spéciaux avant une comparaison de chaines


Sujet :

C#

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    187
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 187
    Points : 73
    Points
    73
    Par défaut Suppression des caractères spéciaux avant une comparaison de chaines
    Bonjour,

    J'ai dans la BDD de mon application de nombreuses données alphanumériques (noms, prénoms, noms de club, noms de villes, etc...) pouvant contenir des accents ou des caractères spéciaux.

    Pour éviter la saisie de doublons, ou pour rechercher des éventuels doublons, je souhaite donc créer une fonction qui supprime les caractères spéciaux et les accents, avant de lancer la recherche sur une chaine de caractère.

    Ce remplacement peut être effectué directement dans une requête, et dans ce cas, la fonction utilisée est une fonction stockée avec ma BDD :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    -- Function: fct_format_string3(text)
    -- DROP FUNCTION fct_format_string3(text);
    CREATE OR REPLACE FUNCTION fct_format_string3(text)
      RETURNS text AS
    $BODY$
        SELECT replace(translate(translate(replace(replace(LOWER($1),'æ','ae'),'œ','oe'), 'âäàéèêëîïöôûü', 'aaaeeeeiioouu'), '&$*@^#- _', ''),'''','');
    $BODY$
      LANGUAGE sql VOLATILE
      COST 100;
    ALTER FUNCTION fct_format_string3(text) OWNER TO postgres;
    Mais je peux également avoir besoin d'utiliser cette fonction à d'autres endroits. Pour éviter de solliciter le serveur inutilement, j'ai donc créé une fonction qui fait la même chose en C# :
    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
     
    public static string fctFormatString(string text)
    {
    	// Récupération de la chaine de caractère originale et passage en minuscule
    	StringBuilder newText = new StringBuilder(text.ToLower());
     
    	// Gestion des "accents"
    	// -> déclaration de variables de conversion "accents"
    	string accent = "àáâãäåòóôõöøèéêëìíîïùúûüÿñç";
    	string sansAccent = "aaaaaaooooooeeeeiiiiuuuuync";
    	// -> conversion des chaines en tableaux de caractères
    	char[] tabAccent = accent.ToCharArray();
    	char[] tabSansAccent = sansAccent.ToCharArray();
    	// -> pour chaque accent, remplacement
    	for (int i = 0; i < accent.Length; i++)
    	{
    		newText.Replace(tabAccent[i].ToString(), tabSansAccent[i].ToString());
    	}
     
    	// Gestion des "caractères spéciaux"
    	// -> déclaration de la variable de conversion "caractères spéciaux"
    	string carSpeciaux = "&$*@^#- _";
    	// -> conversion des chaines en tableaux de caractères
    	char[] tabCarSpeciaux = carSpeciaux.ToCharArray();
    	// -> pour chaque caractère spécial, remplacement
    	for (int i = 0; i < carSpeciaux.Length; i++)
    	{
    		newText.Replace(tabCarSpeciaux[i].ToString(), "");
    	}
     
    	// Gestion des "æ" et "œ"
    	newText.Replace("æ", "ae");
    	newText.Replace("œ", "oe");
     
    	return newText.ToString();
    }
    Je me demande cependant si une telle fonction est vraiment intéressante par rapport à la fonction SQL en terme de performances? Y a t'il moyen de l'optimiser?

    Merci,

  2. #2
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 317
    Points
    13 317
    Par défaut
    Quel type de SGBD ?

    Si c'est SQL Server 2008, tu peux spécifier la collating sequence au niveau de la requête.

    EDIT : à voir le SQL, c'est PostGreSql, donc ma remarque ne s'applique pas.

  3. #3
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Essaie ça plutôt :

    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
     
    using System;
    using System.Text;
    using System.Globalization;
     
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                string str1 = "$Lætitia*";
                string str2 = "^Laëtitia+";
     
                string str3 = RemoveDiacritics(str1);
                string str4 = RemoveDiacritics(str2);
     
                Console.WriteLine(string.Format("{0} => {1}", str1, str3));
                Console.WriteLine(string.Format("{0} => {1}", str2, str4));
                Console.WriteLine(string.Format("{0} = {1} ? {2}", str1, str2, (str1 == str2)));
                Console.WriteLine(string.Format("{0} = {1} ? {2}", str3, str4, (str3 == str4)));
                Console.ReadKey(true);
            }
     
            public static String RemoveDiacritics(String s)
            {
                String normalizedString = s.Normalize(NormalizationForm.FormD);
                StringBuilder stringBuilder = new StringBuilder();
     
                for (int i = 0; i < normalizedString.Length; i++)
                {
                    Char c = normalizedString[i];
                    if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
                    {
                        if ("&$*@^#-+_".IndexOf(c) != -1)
                        {
                            continue;
                        }
                        if (c == 'æ')
                        {
                            stringBuilder.Append('a');
                            stringBuilder.Append('e');
                        }
                        else if (c == 'œ')
                        {
                            stringBuilder.Append('o');
                            stringBuilder.Append('e');
                        }
                        else
                        {
                            stringBuilder.Append(c);
                        }
                    }
                }
     
                return stringBuilder.ToString();
            }
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $Lætitia* => Laetitia
    ^Laëtitia+ => Laetitia
    $Lætitia* = ^Laëtitia+ ? False
    Laetitia = Laetitia ? True

  4. #4
    Modérateur

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Avril 2007
    Messages
    1 996
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 996
    Points : 3 106
    Points
    3 106
    Par défaut
    Bonjour,

    pour les accents, tu as moyen de faire plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public string removeDiacritics(string uneChaine){
    byte[] bytes = System.Text.Encoding.GetEncoding(1251).GetBytes(uneChaine);
    return System.Text.Encoding.ASCII.GetString(bytes);
    }

  5. #5
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Ca marche avec n'importe quel accent ?

    Y compris les trucs du genre Š ά ẫ ?

  6. #6
    Modérateur

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Avril 2007
    Messages
    1 996
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 996
    Points : 3 106
    Points
    3 106
    Par défaut
    A tester, normalement oui, mais je n'ai plus de VS pour faire le test

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Citation Envoyé par calagan99 Voir le message
    Bonjour,

    pour les accents, tu as moyen de faire plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public string removeDiacritics(string uneChaine){
    byte[] bytes = System.Text.Encoding.GetEncoding(1251).GetBytes(uneChaine);
    return System.Text.Encoding.ASCII.GetString(bytes);
    }
    Ca fait un peu bidouille quand même de passer par l'encodage Cyrillique pour faire ça... mais effectivement ça fonctionne, j'y croyais pas avant de tester

    Sinon il y a une méthode d'extension RemoveDiacritics dans la lib Dvp.NET, qui fait ça proprement. Par contre ça enlève seulement les lettres accentuées (remplacées par leur version non accentuée), pas les autres caractères spéciaux.

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Citation Envoyé par calagan99 Voir le message
    A tester, normalement oui, mais je n'ai plus de VS pour faire le test
    LINQPad

  9. #9
    Modérateur

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Avril 2007
    Messages
    1 996
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 996
    Points : 3 106
    Points
    3 106
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Ah, je ne connaissais pas
    Je vais me pencher dessus parce que je n'ai pas la possibilité d'avoir VS dans mon nouveau job et j'avoue que quelques petits devs perso pour manipuler des fichiers me seraient bien utiles.

  10. #10
    Membre éprouvé Avatar de kheironn
    Homme Profil pro
    Chef de projets technique C# / MVC / .Net
    Inscrit en
    Février 2007
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets technique C# / MVC / .Net
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2007
    Messages : 822
    Points : 1 108
    Points
    1 108
    Par défaut
    Allez, je te donne la mienne (trouvée sur le net) que j'utilise depuis un moment déjà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    private string RemoveDiacritics(string s)
          {
             string normalizedString = s.Normalize(NormalizationForm.FormD);
             StringBuilder stringBuilder = new StringBuilder();
     
             for(int i = 0; i < normalizedString.Length; i++)
             {
                Char c = normalizedString[i];
                if(CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
                   stringBuilder.Append(c);
             }
     
             return stringBuilder.ToString();
          }
    En même temps, ça me permettra d'avoir des critiques sur cette façon de faire (lol)

  11. #11
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par kheironn Voir le message
    Allez, je te donne la mienne (trouvée sur le net) que j'utilise depuis un moment déjà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    private string RemoveDiacritics(string s)
          {
             string normalizedString = s.Normalize(NormalizationForm.FormD);
             StringBuilder stringBuilder = new StringBuilder();
     
             for(int i = 0; i < normalizedString.Length; i++)
             {
                Char c = normalizedString[i];
                if(CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
                   stringBuilder.Append(c);
             }
     
             return stringBuilder.ToString();
          }
    En même temps, ça me permettra d'avoir des critiques sur cette façon de faire (lol)
    C'est celle que j'ai posté, en l'améliorant pour traiter certains caractères en plus :o

  12. #12
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Citation Envoyé par kheironn Voir le message
    En même temps, ça me permettra d'avoir des critiques sur cette façon de faire (lol)
    C'est à fondamentalement la même que celle de DVP.net

    Cordialement !

  13. #13
    Membre éprouvé Avatar de kheironn
    Homme Profil pro
    Chef de projets technique C# / MVC / .Net
    Inscrit en
    Février 2007
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets technique C# / MVC / .Net
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2007
    Messages : 822
    Points : 1 108
    Points
    1 108
    Par défaut
    Citation Envoyé par Sehnsucht Voir le message
    C'est à fondamentalement la même que celle de DVP.net

    Cordialement !
    Donc Dvp.Net a googlisé pour faire cette méthode ?
    Je dois utiliser cette méthode depuis deux ou trois ans... sans jamais avoir utilisé dvp.Net

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    187
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 187
    Points : 73
    Points
    73
    Par défaut
    Merci à vous pour vos réponses. J'aurais maintenant une autre question liée à cette méthode.

    J'utilise les composants DevExpress dans mon projet. Pour afficher les données, j'utilise notamment les GridControl/GridView. Il existe alors un panneau de recherche FindPanel, permettant de filtrer les données de la GridView sur la chaine de caratères rentrée dans le FindPanel.

    J'aurais donc voulu que ce filtre prenne en compte la méthode RemoveDiacritics(), afin que l'utilisateur n'ait pas à se soucier de la casse, des accents ou des caractères spéciaux lorsqu'il essaie de rechercher un enregistrment.

    Le problème c'est que le filtre se construit dynamiquement, à partir d'une méthode Contains([ColumnName], "Text"), et que je ne peux donc pas appliquer la méthode RemoveDiacritics() aux lignes de la GridView.

    Voyez vous une solution permettant de coutourner cela?
    Je voudrais que l'affichage "réel" reste affiché, mais que le test se fasse bien sur la chaine "traitée" par RemoveDiacritics()...

Discussions similaires

  1. Suppression des caractères spéciaux
    Par chebmo90 dans le forum Windows Forms
    Réponses: 3
    Dernier message: 30/06/2009, 15h44
  2. Mettre des caractères spéciaux dans une déclaration
    Par Gunner4902 dans le forum Langage
    Réponses: 2
    Dernier message: 23/06/2008, 21h02
  3. [RegEx] Suppression des caractères spéciaux et nombres
    Par kenny.kev dans le forum Langage
    Réponses: 6
    Dernier message: 03/03/2008, 16h53
  4. Réponses: 9
    Dernier message: 31/07/2007, 01h13
  5. suppression des caratères spéciaux dans une table
    Par syl221 dans le forum Access
    Réponses: 6
    Dernier message: 31/08/2005, 09h20

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