2010-03-02 33 views
14

我使用此方法從我刪除字符串的口音:爲什麼刪除口音時不Đ得到夷爲平地,d /變音符號

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(); 
} 

但這種方法留下的DJ DJ和不改變到d,儘管d是它的基本字符。 你可以試試這個輸入字符串「æøåáâăăäĺĺćçčéęëěíîďđńňóôőøřůúűüýţ」

字母đ中有什麼特別之處?

+0

您能否以「\ uxxxx」等形式顯示重寫字符串字面值?這將使複製更容易,而不必擔心將字符組合在一起等。 – 2010-03-02 11:49:56

+0

這是一個土耳其(或其他東歐字符)? – leppie 2010-03-02 11:51:31

+0

這是一個巴爾幹字符:-) – 2010-03-02 12:10:17

回答

13

的答案爲什麼它不工作是認爲「d是其基礎炭」的說法是錯誤的。 U + 0111(帶有筆劃的拉丁文小寫字母D)具有Unicode類別「Letter,小寫字母」並且沒有分解映射(即,它不分解爲「d」,後面跟着一個組合標記)。

"đ".Normalize(NormalizationForm.FormD)只是返回"đ",由於它不是非間距標記,所以不會被循環除去。

「ø」和Unicode不提供分解映射的其他字母也存在類似的問題。 (如果你試圖找到「最好的」ASCII字符來表示一個Unicode字母,這種方法根本不適用於西里爾文,希臘文,中文或其他非拉丁字母;如果你遇到問題,你也會遇到問題if例如,你想用「ß」音譯爲「ss」,使用類似UnidecodeSharp這樣的庫可能會有所幫助。)

3

我不得不承認,我不知道爲什麼這工作,但它肯定似乎

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

=>「aoaaaaalccceeeeiiddnnooooruuuuyt」

+0

我想知道爲什麼這個工程太! – 2010-03-02 12:49:54

+1

「西里爾文」編碼似乎有一個小表格,它將在輸入字符未出現在代碼頁1251中時使用。這感覺就像是濫用無證行爲。它還會將「ß」(和任何其他無法識別的字符)轉換爲「?」,這可能是不恰當的(正如將'æ'轉換爲'a'一樣)。對於(幾乎完整的)Unicode音譯,請查看http://unidecode.codeplex.com/。 – 2010-11-28 22:17:43

+0

是的,這當然是一個黑客。 Unidecode如何與Iconv // TRANSLIT進行比較? – 2010-11-29 08:58:33

3

D with stroke」(維基百科)以多種語言使用,並且在所有這些文字中似乎都被視爲一封截然不同的文字 - 這就是爲什麼它保持不變。

+0

此外,古英語中的eth突變爲英語中的「th」,而在挪威中則變成「d」。除了與資本d的表面相似之外,它完全不同。 – 2010-03-02 12:33:18

+0

是的,但同樣適用於č或ć,這也是一封明確的字母。 – 2010-03-02 12:49:08

+0

具體而言,Unicode定義了đ的分解映射(雖然它適用於č和å,其他字母認爲它們是不同的字母)。 – 2010-11-28 22:08:38

-4

這應該工作

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

這看起來就像原來的海報代碼FormKD改爲FormD(和小的文體變化)。這不適用於其他答案中給出的原因。 – 2010-12-02 14:27:11

+0

我一直使用FormD直到現在,我不知道這個問題,但正如我所看到的(我剛剛測試過)你是對的。它不起作用。 – mare 2010-12-02 20:24:31