2010-03-02 6 views
14

Entfernen Ich benutze diese Methode Akzente aus meiner Strings zu entfernen:Warum D abgeflacht Đ bekommen nicht, wenn Akzente/Diacritics

static string RemoveAccents(string input) 
{ 
    string normalized = input.Normalize(NormalizationForm.FormKD); 
    StringBuilder builder = new StringBuilder(); 
    foreach (char c in normalized) 
    { 
     if (char.GetUnicodeCategory(c) != 
     UnicodeCategory.NonSpacingMark) 
     { 
      builder.Append(c); 
     } 
    } 
    return builder.ToString(); 
} 

aber diese Methode lässt đ als DJ- und es ändert sich nicht zu d, obwohl d ist seine Basis char. Sie können es versuchen, mit diesem Eingabestring „æøåáâăäĺćçčéęëěíîďđńňóôőöřůúűüýţ“

Was in Brief đ so besonders?

+0

Könnten Sie das String-Literal in der Form "\ uxxxx" usw. neu schreiben? Das macht es einfacher zu reprozieren, ohne sich Gedanken über die Kombination von Charakteren etc. machen zu müssen. –

+0

Ist das ein türkischer (oder ein anderer osteuropäischer Charakter)? – leppie

+0

Es ist ein Balkan Charakter :-) –

Antwort

13

Die Antwort für arbeiten, warum dies nicht den Fall funktioniert, dass die Aussage, dass falsch ist „d seine Basis char ist“. U + 0111 (LATEIN KLEINER BRIEF D MIT HUB) hat die Unicode-Kategorie "Brief, Kleinbuchstabe" und hat keine Dekompositionskartierung (d. H. Es zerfällt nicht zu "d", gefolgt von einer Kombinationsmarkierung).

"đ".Normalize(NormalizationForm.FormD) gibt einfach "đ" zurück, die nicht von der Schleife entfernt wird, da es keine Nicht-Abstandsmarkierung ist.

Ein ähnliches Problem tritt für "ø" und andere Buchstaben auf, für die Unicode keine Dekompositionszuordnung bereitstellt. (Und wenn Sie versuchen, das "beste" ASCII-Zeichen für einen Unicode-Buchstaben zu finden, funktioniert dieser Ansatz für kyrillische, griechische, chinesische oder andere nicht-lateinische Alphabete überhaupt nicht. Sie werden auch Probleme bekommen, wenn B. mit Hilfe einer Bibliothek wie UnidecodeSharp.

3

Ich muss zugeben, dass ich nicht sicher bin, warum das funktioniert, aber es scheint sicher zu

var str = "æøåáâăäĺćçčéęëěíîďđńňóôőöřůúűüýţ"; 
var noApostrophes = Encoding.ASCII.GetString(Encoding.GetEncoding("Cyrillic").GetBytes(str)); 

=> "aoaaaaalccceeeeiiddnnooooruuuuyt"

+0

ich würde gerne wissen, warum das auch funktioniert! –

+1

Die Codierung "Kyrillisch" scheint eine kleine Tabelle mit Ersatzzeichen zu enthalten, die verwendet wird, wenn das Eingabezeichen nicht in Codepage 1251 erscheint. Das fühlt sich an wie ein Missbrauch dieses undokumentierten Verhaltens. Es wandelt auch "ß" (und jedes andere nicht erkannte Zeichen) in "?" Um, was unangemessen sein kann (ebenso wie die Umwandlung von "æ" in "a"). Für (fast vollständige) Unicode-Transliteration lesen Sie http://unidecode.codeplex.com/. –

+0

Ja, es ist sicherlich ein Hack. Wie vergleicht Unidecode mit Iconv // TRANSLIT? –

3

"D with stroke" (Wikipedia) in mehreren Sprachen verwendet wird, und scheint in jedem von ihnen ein eindeutiger Buchstabe zu sein - und deshalb bleibt es unverändert.

+0

Eth in Old English mutierte im Englischen zu "th", während es in Norwegisch zu "d" wurde. Abgesehen von einer oberflächlichen Ähnlichkeit mit Kapital d ist das völlig anders. –

+0

Ja, aber das gleiche gilt für č oder ć, was auch ein eindeutiger Buchstabe ist. –

+0

Insbesondere definiert Unicode keine Dekompositionszuordnung für đ (während es für è und å gilt, die von einigen anderen Alphabeten als getrennte Buchstaben betrachtet werden). –

-4

soll diese

private static String RemoveDiacritics(string text) 
    { 
     String normalized = text.Normalize(NormalizationForm.FormD); 
     StringBuilder sb = new StringBuilder(); 

     for (int i = 0; i < normalized.Length; i++) 
     { 
      Char c = normalized[i]; 
      if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark) 
       sb.Append(c); 
     } 

     return sb.ToString(); 
    } 
+0

Das sieht genauso aus wie der ursprüngliche Code des Posters mit FormKD geändert zu FormD (und kleinere stilistische Änderungen).Dies wird aus den in anderen Antworten angegebenen Gründen nicht funktionieren. –

+0

Ich habe FormD die ganze Zeit bis jetzt verwendet und ich war mir dieses Problems nicht bewusst, aber wie ich sehen kann (ich habe es gerade getestet), hast du Recht. Es funktioniert nicht. – mare