2012-10-26 49 views
1

我通過WebClient將簽名的XML發送到網關。現在我必須確保節點值只包含德文字母。我有2個測試詞。第一得到很好通過使用轉換:如何使用Encoding去除特定字符

string foreignString = "Łůj꣥ü"; 
Encoding utf8 = Encoding.UTF8; 
Encoding iso = Encoding.GetEncoding("ISO-8859-1"); 
byte[] utfBytes = Encoding.Convert(iso, utf8, iso.GetBytes(foreignString)); 
string result = utf8.GetString(utfBytes); 

但第二串中是也包括在UTF-8編碼的字符。它的

ç (Latin small letter c with cedilla) 

經過與其他編碼一點點測試後,我總是得到相同的結果:字符總是在那裏。什麼是有道理的,因爲它是UTF-8表的一部分:)

所以我的問題是:有沒有一種方法來掩蓋掉所有的法語,葡萄牙語和西班牙語字符,而不會丟掉德語變音符號?

在此先感謝!

回答

2

您可以根據ISO-8859-1編碼與額外的特殊規則,創建自己的Encoding類:

class GermanEncoding : Encoding { 

    static readonly Encoding iso88791Encoding = Encoding.GetEncoding("ISO-8859-1"); 

    static readonly Dictionary<Char, Char> charMappingTable = new Dictionary<Char, Char> { 
    { 'À', 'A' }, 
    { 'Á', 'A' }, 
    { 'Â', 'A' }, 
    { 'ç', 'c' }, 
    // Add more mappings 
    }; 

    static readonly Dictionary<Byte, Byte> byteMappingTable = charMappingTable 
    .ToDictionary(kvp => MapCharToByte(kvp.Key), kvp => MapCharToByte(kvp.Value)); 

    public override Int32 GetByteCount(Char[] chars, Int32 index, Int32 count) { 
    return iso88791Encoding.GetByteCount(chars, index, count); 
    } 

    public override Int32 GetBytes(Char[] chars, Int32 charIndex, Int32 charCount, Byte[] bytes, Int32 byteIndex) { 
    var count = iso88791Encoding.GetBytes(chars, charIndex, charCount, bytes, byteIndex); 
    for (var i = byteIndex; i < byteIndex + count; ++i) 
     if (byteMappingTable.ContainsKey(bytes[i])) 
     bytes[i] = byteMappingTable[bytes[i]]; 
    return count; 
    } 

    public override Int32 GetCharCount(Byte[] bytes, Int32 index, Int32 count) { 
    return iso88791Encoding.GetCharCount(bytes, index, count); 
    } 

    public override Int32 GetChars(Byte[] bytes, Int32 byteIndex, Int32 byteCount, Char[] chars, Int32 charIndex) { 
    return iso88791Encoding.GetChars(bytes, byteIndex, byteCount, chars, charIndex); 
    } 

    public override Int32 GetMaxByteCount(Int32 charCount) { 
    return iso88791Encoding.GetMaxByteCount(charCount); 
    } 

    public override Int32 GetMaxCharCount(Int32 byteCount) { 
    return iso88791Encoding.GetMaxCharCount(byteCount); 
    } 

    static Byte MapCharToByte(Char c) { 
    // NOTE: Assumes that each character encodes as a single byte. 
    return iso88791Encoding.GetBytes(new[] { c })[0]; 
    } 

} 

這種編碼是基於您要使用的ISO-8859-事實1編碼,並在其中要將「非德語」字符映射到它們的ASCII等效字符處。內置的ISO-8859-1編碼知道如何映射ŁL,並且由於ISO-8859-1是單字節字符集,所以您可以對字節進行額外映射,因爲每個字節都對應一個字符。這在GetBytes方法中完成。

您可以使用此代碼 「乾淨」 的字符串:

var encoding = new GermanEncoding(); 
string foreignString = "Łůj꣥üç"; 
var bytes = encoding.GetBytes(foreignString); 
var result = encoding.GetString(bytes); 

結果字符串是LujeLAüc

請注意,該實現非常簡單,它使用字典來執行額外的字節映射步驟。這可能效率不高,但在這種情況下,您可以考慮使用256字節映射數組等替代方法。此外,您需要展開charMappingTable以包含要執行的所有其他映射。

+0

感謝您的好解決方案! – csteinmueller