Comment puis-je supprimer les diacritiques (accents) d'une chaîne de caractères in.NET Je ne sais pas.

j'essaie de convertir quelques cordes qui sont en Canadien français et en gros, j'aimerais pouvoir enlever les marques d'accent français dans les lettres tout en gardant la lettre. (P. ex. convertir é en e , de sorte que crème brûlée deviendrait creme brulee )

Quelle est la meilleure méthode pour y parvenir?

350
demandé sur Colonel Panic 2008-10-30 05:07:46

17 réponses

Je n'ai pas utilisé cette méthode, mais Michael Kaplan décrit une méthode pour le faire dans son blog (avec un titre confus) qui parle de diacritiques stripping: Stripping est un travail intéressant (aka Sur le sens de sans signification, alias tout Les caractères Mn ne sont pas espacés, mais certains sont plus non-espacement de autres)

static string RemoveDiacritics(string text) 
{
    var normalizedString = text.Normalize(NormalizationForm.FormD);
    var stringBuilder = new StringBuilder();

    foreach (var c in normalizedString)
    {
        var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
        if (unicodeCategory != UnicodeCategory.NonSpacingMark)
        {
            stringBuilder.Append(c);
        }
    }

    return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
}

notez qu'il s'agit d'une suite à son billet précédent: Stripping diacritics....

L'approche utilise des de la Chaîne.Normalisez pour séparer la chaîne de caractères en glyphes constitutifs (en séparant essentiellement les caractères" de base " des diacritiques), puis numérise le résultat et ne conserve que les caractères de base. C'est juste un peu compliqué, mais en fait, tu as devant toi un problème compliqué.

bien sûr, si vous vous limitez au français, vous pourriez probablement vous en tirer avec l'approche simple basée sur la table en Comment supprimer les accents et tilde en C++ std::string , comme recommandé par @David Dibben.

436
répondu Blair Conrad 2017-05-21 21:02:40

cela a fait l'affaire pour moi...

string accentedStr;
byte[] tempBytes;
tempBytes = System.Text.Encoding.GetEncoding("ISO-8859-8").GetBytes(accentedStr);
string asciiStr = System.Text.Encoding.UTF8.GetString(tempBytes);

rapide et court!

122
répondu azrafe7 2010-01-18 14:16:44

si quelqu'un est intéressé, je cherchais quelque chose de similaire et j'ai fini par écrire ce qui suit:

    public static string NormalizeStringForUrl(string name)
    {
        String normalizedString = name.Normalize(NormalizationForm.FormD);
        StringBuilder stringBuilder = new StringBuilder();

        foreach (char c in normalizedString)
        {
            switch (CharUnicodeInfo.GetUnicodeCategory(c))
            {
                case UnicodeCategory.LowercaseLetter:
                case UnicodeCategory.UppercaseLetter:
                case UnicodeCategory.DecimalDigitNumber:
                    stringBuilder.Append(c);
                    break;
                case UnicodeCategory.SpaceSeparator:
                case UnicodeCategory.ConnectorPunctuation:
                case UnicodeCategory.DashPunctuation:
                    stringBuilder.Append('_');
                    break;
            }
        }
        string result = stringBuilder.ToString();
        return String.Join("_", result.Split(new char[] { '_' }
            , StringSplitOptions.RemoveEmptyEntries)); // remove duplicate underscores
    }
27
répondu Luk 2009-04-23 08:32:00

si quelqu'un est intéressé, voici l'équivalent java:

import java.text.Normalizer;

public class MyClass
{
    public static String removeDiacritics(String input)
    {
        String nrml = Normalizer.normalize(input, Normalizer.Form.NFD);
        StringBuilder stripped = new StringBuilder();
        for (int i=0;i<nrml.length();++i)
        {
            if (Character.getType(nrml.charAt(i)) != Character.NON_SPACING_MARK)
            {
                stripped.append(nrml.charAt(i));
            }
        }
        return stripped.toString();
    }
}
13
répondu KenE 2009-09-09 18:17:19

j'utilise souvent une méthode d'extension basée sur une autre version que j'ai trouvé ici (voir en remplacement des caractères C# (ascii) ) Une explication rapide:

  • la Normalisation de la forme D divise charactes comme è à une e et un nonspacing `
  • A partir de cela, les caractères de nospacing sont supprimés
  • le résultat est normalisé retour à le formulaire C (je ne suis pas sûr si cela est nécessaire)

Code:

using System.Linq;
using System.Text;
using System.Globalization;

// namespace here
public static class Utility
{
    public static string RemoveDiacritics(this string str)
    {
        if (null == str) return null;
        var chars =
            from c in str.Normalize(NormalizationForm.FormD).ToCharArray()
            let uc = CharUnicodeInfo.GetUnicodeCategory(c)
            where uc != UnicodeCategory.NonSpacingMark
            select c;

        var cleanStr = new string(chars.ToArray()).Normalize(NormalizationForm.FormC);

        return cleanStr;
    }

    // or, alternatively
    public static string RemoveDiacritics2(this string str)
    {
        if (null == str) return null;
        var chars = str
            .Normalize(NormalizationForm.FormD)
            .ToCharArray()
            .Where(c=> CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
            .ToArray();

        return new string(chars).Normalize(NormalizationForm.FormC);
    }
}
12
répondu realbart 2018-03-09 13:01:07

j'ai eu besoin de quelque chose qui convertit tous les caractères unicode principaux et la réponse votée a quitté quelques-uns donc j'ai créé une version de Codeigniter's convert_accented_characters($str) en C# qui est facilement personnalisable:

using System;
using System.Text;
using System.Collections.Generic;

public static class Strings
{
    static Dictionary<string, string> foreign_characters = new Dictionary<string, string>
    {
        { "äæǽ", "ae" },
        { "öœ", "oe" },
        { "ü", "ue" },
        { "Ä", "Ae" },
        { "Ü", "Ue" },
        { "Ö", "Oe" },
        { "ÀÁÂÃÄÅǺĀĂĄǍΑΆẢẠẦẪẨẬẰẮẴẲẶА", "A" },
        { "àáâãåǻāăąǎªαάảạầấẫẩậằắẵẳặа", "a" },
        { "Б", "B" },
        { "б", "b" },
        { "ÇĆĈĊČ", "C" },
        { "çćĉċč", "c" },
        { "Д", "D" },
        { "д", "d" },
        { "ÐĎĐΔ", "Dj" },
        { "ðďđδ", "dj" },
        { "ÈÉÊËĒĔĖĘĚΕΈẼẺẸỀẾỄỂỆЕЭ", "E" },
        { "èéêëēĕėęěέεẽẻẹềếễểệеэ", "e" },
        { "Ф", "F" },
        { "ф", "f" },
        { "ĜĞĠĢΓГҐ", "G" },
        { "ĝğġģγгґ", "g" },
        { "ĤĦ", "H" },
        { "ĥħ", "h" },
        { "ÌÍÎÏĨĪĬǏĮİΗΉΊΙΪỈỊИЫ", "I" },
        { "ìíîïĩīĭǐįıηήίιϊỉịиыї", "i" },
        { "Ĵ", "J" },
        { "ĵ", "j" },
        { "ĶΚК", "K" },
        { "ķκк", "k" },
        { "ĹĻĽĿŁΛЛ", "L" },
        { "ĺļľŀłλл", "l" },
        { "М", "M" },
        { "м", "m" },
        { "ÑŃŅŇΝН", "N" },
        { "ñńņňʼnνн", "n" },
        { "ÒÓÔÕŌŎǑŐƠØǾΟΌΩΏỎỌỒỐỖỔỘỜỚỠỞỢО", "O" },
        { "òóôõōŏǒőơøǿºοόωώỏọồốỗổộờớỡởợо", "o" },
        { "П", "P" },
        { "п", "p" },
        { "ŔŖŘΡР", "R" },
        { "ŕŗřρр", "r" },
        { "ŚŜŞȘŠΣС", "S" },
        { "śŝşșšſσςс", "s" },
        { "ȚŢŤŦτТ", "T" },
        { "țţťŧт", "t" },
        { "ÙÚÛŨŪŬŮŰŲƯǓǕǗǙǛŨỦỤỪỨỮỬỰУ", "U" },
        { "ùúûũūŭůűųưǔǖǘǚǜυύϋủụừứữửựу", "u" },
        { "ÝŸŶΥΎΫỲỸỶỴЙ", "Y" },
        { "ýÿŷỳỹỷỵй", "y" },
        { "В", "V" },
        { "в", "v" },
        { "Ŵ", "W" },
        { "ŵ", "w" },
        { "ŹŻŽΖЗ", "Z" },
        { "źżžζз", "z" },
        { "ÆǼ", "AE" },
        { "ß", "ss" },
        { "IJ", "IJ" },
        { "ij", "ij" },
        { "Œ", "OE" },
        { "ƒ", "f" },
        { "ξ", "ks" },
        { "π", "p" },
        { "β", "v" },
        { "μ", "m" },
        { "ψ", "ps" },
        { "Ё", "Yo" },
        { "ё", "yo" },
        { "Є", "Ye" },
        { "є", "ye" },
        { "Ї", "Yi" },
        { "Ж", "Zh" },
        { "ж", "zh" },
        { "Х", "Kh" },
        { "х", "kh" },
        { "Ц", "Ts" },
        { "ц", "ts" },
        { "Ч", "Ch" },
        { "ч", "ch" },
        { "Ш", "Sh" },
        { "ш", "sh" },
        { "Щ", "Shch" },
        { "щ", "shch" },
        { "ЪъЬь", "" },
        { "Ю", "Yu" },
        { "ю", "yu" },
        { "Я", "Ya" },
        { "я", "ya" },
    };

    public static char RemoveDiacritics(this char c){
        foreach(KeyValuePair<string, string> entry in foreign_characters)
        {
            if(entry.Key.IndexOf (c) != -1)
            {
                return entry.Value[0];
            }
        }
        return c;
    }

    public static string RemoveDiacritics(this string s) 
    {
        //StringBuilder sb = new StringBuilder ();
        string text = "";


        foreach (char c in s)
        {
            int len = text.Length;

            foreach(KeyValuePair<string, string> entry in foreign_characters)
            {
                if(entry.Key.IndexOf (c) != -1)
                {
                    text += entry.Value;
                    break;
                }
            }

            if (len == text.Length) {
                text += c;  
            }
        }
        return text;
    }
}

Utilisation

// for strings
"crème brûlée".RemoveDiacritics (); // creme brulee

// for chars
"Ã"[0].RemoveDiacritics (); // A
11
répondu CIRCLE 2015-12-14 21:53:51

de La page de Codes de grec (ISO) peut le faire

l'information sur cette page de code est dans System.Text.Encoding.GetEncodings() . En savoir plus sur in: https://msdn.microsoft.com/pt-br/library/system.text.encodinginfo.getencoding (v=V110).aspx

Grec (ISO) a codepage 28597 et nom iso-8859-7 .

aller au code... \o/

string text = "Você está numa situação lamentável";

string textEncode = System.Web.HttpUtility.UrlEncode(text, Encoding.GetEncoding("iso-8859-7"));
//result: "Voce+esta+numa+situacao+lamentavel"

string textDecode = System.Web.HttpUtility.UrlDecode(textEncode);
//result: "Voce esta numa situacao lamentavel"

alors, écrivez cette fonction...

public string RemoveAcentuation(string text)
{
    return
        System.Web.HttpUtility.UrlDecode(
            System.Web.HttpUtility.UrlEncode(
                text, Encoding.GetEncoding("iso-8859-7")));
}

notez cela... Encoding.GetEncoding("iso-8859-7") est équivalent à Encoding.GetEncoding(28597) parce que le premier est le nom, et le second la page de codage de L'encodage.

6
répondu Sergio Cabral 2016-08-05 01:46:49

cela fonctionne très bien en java.

il convertit fondamentalement tous les caractères accentués en leurs homologues désaccentés suivi par leur diacritiques de combinaison. Maintenant vous pouvez utiliser une expression régulière pour enlever les signes diacritiques.

import java.text.Normalizer;
import java.util.regex.Pattern;

public String deAccent(String str) {
    String nfdNormalizedString = Normalizer.normalize(str, Normalizer.Form.NFD); 
    Pattern pattern = Pattern.compile("\p{InCombiningDiacriticalMarks}+");
    return pattern.matcher(nfdNormalizedString).replaceAll("");
}
3
répondu hashable 2009-07-31 21:22:22

C'est la VERSION VB (fonctionne avec le grec):

Importations Système.Texte

Importations Système.Mondialisation

Public Function RemoveDiacritics(ByVal s As String)
    Dim normalizedString As String
    Dim stringBuilder As New StringBuilder
    normalizedString = s.Normalize(NormalizationForm.FormD)
    Dim i As Integer
    Dim c As Char
    For i = 0 To normalizedString.Length - 1
        c = normalizedString(i)
        If CharUnicodeInfo.GetUnicodeCategory(c) <> UnicodeCategory.NonSpacingMark Then
            stringBuilder.Append(c)
        End If
    Next
    Return stringBuilder.ToString()
End Function
3
répondu Stefanos Michanetzis 2010-07-28 13:21:20

C'est comme ça que je remplace les caractères diacritiques par des caractères non diacritiques dans tout mon programme .NET

C#:

//Transforms the culture of a letter to its equivalent representation in the 0-127 ascii table, such as the letter 'é' is substituted by an 'e'
public string RemoveDiacritics(string s)
{
    string normalizedString = null;
    StringBuilder stringBuilder = new StringBuilder();
    normalizedString = s.Normalize(NormalizationForm.FormD);
    int i = 0;
    char c = '"151900920"';

    for (i = 0; i <= normalizedString.Length - 1; i++)
    {
        c = normalizedString[i];
        if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
        {
            stringBuilder.Append(c);
        }
    }

    return stringBuilder.ToString().ToLower();
}

VB. NET:

'Transforms the culture of a letter to its equivalent representation in the 0-127 ascii table, such as the letter "é" is substituted by an "e"'
Public Function RemoveDiacritics(ByVal s As String) As String
    Dim normalizedString As String
    Dim stringBuilder As New StringBuilder
    normalizedString = s.Normalize(NormalizationForm.FormD)
    Dim i As Integer
    Dim c As Char

    For i = 0 To normalizedString.Length - 1
        c = normalizedString(i)
        If CharUnicodeInfo.GetUnicodeCategory(c) <> UnicodeCategory.NonSpacingMark Then
            stringBuilder.Append(c)
        End If
    Next
    Return stringBuilder.ToString().ToLower()
End Function
2
répondu Heyjee 2013-08-01 18:55:31

vous pouvez utiliser l'extension de corde de MMLib.Extensions paquet nuget:

using MMLib.RapidPrototyping.Generators;
public void ExtensionsExample()
{
  string target = "aácčeéií";
  Assert.AreEqual("aacceeii", target.RemoveDiacritics());
} 

Nuget page: https://www.nuget.org/packages/MMLib.Extensions / Site du projet Codeplex https://mmlib.codeplex.com /

2
répondu Mino 2013-12-30 10:25:13

c'est amusant une telle question peut obtenir tant de réponses, et pourtant aucune ne correspond à mes exigences :) Il ya tant de langues autour, une solution agnostique langue complète est AFAIK pas vraiment possible, comme d'autres a mentionné que le FormC ou FormD donnent des problèmes.

étant donné que la question initiale portait sur le français, la réponse de travail la plus simple est en effet

    public static string ConvertWesternEuropeanToASCII(this string str)
    {
        return Encoding.ASCII.GetString(Encoding.GetEncoding(1251).GetBytes(str));
    }

1251 doit être remplacé par le code d'encodage de la langue d'entrée.

remplacer un seul caractère par un seul caractère. Puisque je travaille aussi avec l'allemand comme entrée, j'ai fait une conversion manuelle

    public static string LatinizeGermanCharacters(this string str)
    {
        StringBuilder sb = new StringBuilder(str.Length);
        foreach (char c in str)
        {
            switch (c)
            {
                case 'ä':
                    sb.Append("ae");
                    break;
                case 'ö':
                    sb.Append("oe");
                    break;
                case 'ü':
                    sb.Append("ue");
                    break;
                case 'Ä':
                    sb.Append("Ae");
                    break;
                case 'Ö':
                    sb.Append("Oe");
                    break;
                case 'Ü':
                    sb.Append("Ue");
                    break;
                case 'ß':
                    sb.Append("ss");
                    break;
                default:
                    sb.Append(c);
                    break;
            }
        }
        return sb.ToString();
    }

il se peut qu'il n'offre pas la meilleure performance, mais au moins il est très facile à lire et étendre. Regex est un non GO, beaucoup plus lent que n'importe quelle chose de char/string.

j'ai aussi une méthode très simple pour enlever l'espace:

    public static string RemoveSpace(this string str)
    {
        return str.Replace(" ", string.Empty);
    }

finalement, j'utilise un combinaison des trois extensions ci-dessus:

    public static string LatinizeAndConvertToASCII(this string str, bool keepSpace = false)
    {
        str = str.LatinizeGermanCharacters().ConvertWesternEuropeanToASCII();            
        return keepSpace ? str : str.RemoveSpace();
    }

et un test de petite unité à celui (non exhaustif) qui réussissent.

    [TestMethod()]
    public void LatinizeAndConvertToASCIITest()
    {
        string europeanStr = "Bonjour ça va? C'est l'été! Ich möchte ä Ä á à â ê é è ë Ë É ï Ï î í ì ó ò ô ö Ö Ü ü ù ú û Û ý Ý ç Ç ñ Ñ";
        string expected = "Bonjourcava?C'estl'ete!IchmoechteaeAeaaaeeeeEEiIiiiooooeOeUeueuuuUyYcCnN";
        string actual = europeanStr.LatinizeAndConvertToASCII();
        Assert.AreEqual(expected, actual);
    }
2
répondu EricBDev 2017-02-06 13:19:11

Try HelperSharp package .

Il y a une méthode RemoveAccents:

 public static string RemoveAccents(this string source)
 {
     //8 bit characters 
     byte[] b = Encoding.GetEncoding(1251).GetBytes(source);

     // 7 bit characters
     string t = Encoding.ASCII.GetString(b);
     Regex re = new Regex("[^a-zA-Z0-9]=-_/");
     string c = re.Replace(t, " ");
     return c;
 }
1
répondu giacomelli 2013-05-03 02:25:24
Imports System.Text
Imports System.Globalization

 Public Function DECODE(ByVal x As String) As String
        Dim sb As New StringBuilder
        For Each c As Char In x.Normalize(NormalizationForm.FormD).Where(Function(a) CharUnicodeInfo.GetUnicodeCategory(a) <> UnicodeCategory.NonSpacingMark)  
            sb.Append(c)
        Next
        Return sb.ToString()
    End Function
1
répondu Tratak 2015-06-22 13:34:46

ce que cette personne a dit:

Encoding.ASCII.GetString(Encoding.GetEncoding(1251).GetBytes(text));

il divise en fait les caractères comme å qui est un caractère (qui est le code de caractère 00E5 , pas 0061 plus le modificateur 030A qui ressemblerait au même) en a plus une sorte de modificateur, et puis la conversion ASCII supprime le modificateur, laissant le seul a .

1
répondu Community 2017-05-23 11:54:59

j'aime vraiment le code concis et fonctionnel fourni par azrafe7 . Donc, je l'ai un peu changé pour le convertir en une méthode d'extension:

public static class StringExtensions
{
    public static string RemoveDiacritics(this string text)
    {
        const string SINGLEBYTE_LATIN_ASCII_ENCODING = "ISO-8859-8";

        if (string.IsNullOrEmpty(text))
        {
            return string.Empty;
        }

        return Encoding.ASCII.GetString(
            Encoding.GetEncoding(SINGLEBYTE_LATIN_ASCII_ENCODING).GetBytes(text));
    }
}
0
répondu Siavash Mortazavi 2017-05-23 12:02:46

si vous n'y avez pas pensé. Regarde comme il existe une gamme complète de tests unitaires avec elle.

https://github.com/thomasgalliker/Diacritics.NET

0
répondu Squiggs 2017-05-21 21:10:25