2010-11-05 112 views
4

我正在構建一個用C#讀取電子郵件的系統。我解析這個主題時遇到了一個問題,我認爲這個問題與編碼有關。C#電子郵件主題解析

我正在閱讀的主題如下:=?ISO-8859-1?Q?=E6=F8sd=E5f=F8sdf_sdfsdf?=,發送的原始主題是æøsdåføsdf sdfsdf(挪威語中的人物)。

任何想法如何改變編碼或解析正確?到目前爲止,我試圖使用C#編碼轉換技術將主題編碼爲utf8,但沒有任何運氣。

這裏是我試過的解決方案之一:

Encoding iso = Encoding.GetEncoding("iso-8859-1"); 
Encoding utf = Encoding.UTF8; 
string decodedSubject = 
    utf.GetString(Encoding.Convert(utf, iso, 
            iso.GetBytes(m.Subject.Split('?')[3]))); 
+0

在上面的例子中,utf和iso在Convert方法中交換。我已經嘗試了正確的方式沒有任何運氣,以及;) – Kenneth 2010-11-05 14:46:58

+0

哦,我會解決:) – Kenneth 2010-11-05 14:50:09

回答

6

編碼被稱爲quoted printable

查看this的問題的答案。

從接受answer改編:

public string DecodeQuotedPrintable(string value) 
{ 
     Attachment attachment = Attachment.CreateAttachmentFromString("", value); 
     return attachment.Name; 
} 

當傳遞的字符串=?ISO-8859-1?Q?=E6=F8sd=E5f=F8sdf_sdfsdf?=這將返回 「æøsdåføsdf_sdfsdf」。

+0

啊,真棒的人。我一直在尋找這個很長一段時間的解決方案:) – Kenneth 2010-11-05 14:56:30

+0

可悲的是,這並不適用於當前版本的ARM上的Mono – TimothyP 2013-01-28 15:16:55

+0

不適用於「=?windows-1256」 – Alex 2013-12-26 12:21:38

6
public static string DecodeEncodedWordValue(string mimeString) 
    { 
     var regex = new Regex(@"=\?(?<charset>.*?)\?(?<encoding>[qQbB])\?(?<value>.*?)\?="); 
     var encodedString = mimeString; 
     var decodedString = string.Empty; 

     while (encodedString.Length > 0) 
     { 
      var match = regex.Match(encodedString); 
      if (match.Success) 
      { 
       // If the match isn't at the start of the string, copy the initial few chars to the output 
       decodedString += encodedString.Substring(0, match.Index); 

       var charset = match.Groups["charset"].Value; 
       var encoding = match.Groups["encoding"].Value.ToUpper(); 
       var value = match.Groups["value"].Value; 

       if (encoding.Equals("B")) 
       { 
        // Encoded value is Base-64 
        var bytes = Convert.FromBase64String(value); 
        decodedString += Encoding.GetEncoding(charset).GetString(bytes); 
       } 
       else if (encoding.Equals("Q")) 
       { 
        // Encoded value is Quoted-Printable 
        // Parse looking for =XX where XX is hexadecimal 
        var regx = new Regex("(\\=([0-9A-F][0-9A-F]))", RegexOptions.IgnoreCase); 
        decodedString += regx.Replace(value, new MatchEvaluator(delegate(Match m) 
        { 
         var hex = m.Groups[2].Value; 
         var iHex = Convert.ToInt32(hex, 16); 

         // Return the string in the charset defined 
         var bytes = new byte[1]; 
         bytes[0] = Convert.ToByte(iHex); 
         return Encoding.GetEncoding(charset).GetString(bytes); 
        })); 
        decodedString = decodedString.Replace('_', ' '); 
       } 
       else 
       { 
        // Encoded value not known, return original string 
        // (Match should not be successful in this case, so this code may never get hit) 
        decodedString += encodedString; 
        break; 
       } 

       // Trim off up to and including the match, then we'll loop and try matching again. 
       encodedString = encodedString.Substring(match.Index + match.Length); 
      } 
      else 
      { 
       // No match, not encoded, return original string 
       decodedString += encodedString; 
       break; 
      } 
     } 
     return decodedString; 
    } 
+1

順便說一句,遇到更多的問題解析電子郵件主題和內容;例如ascii和en.wikipedia.org/wiki/MIME#Encoded-Word的組合,我發現另一種解決方案能夠使用正則表達式和逐字節轉換解析編碼字和ascii組合。將解決方案粘貼到更新標籤上以供參考(並不是因爲我在某個論壇上發現該解決方案而獲得讚譽,也沒有記住網址tho)。編輯:試圖添加編碼字標籤,但由於不允許創建新標籤beeing .. – Kenneth 2010-11-08 13:15:08

+0

我在正則表達式的開始添加「\ s *」。有時我們有幾個編碼部分用空格分隔。 – Trurl 2014-03-24 12:14:37

+0

@Kenneth非常感謝你,這正是我所需要的。這不僅僅是使用普通的Quoted-Printable解碼器,因爲它們不考慮前綴'=?ISO-8859-1?Q?' – silkfire 2015-10-15 09:41:02