拆分来自gmail的响应字符串

时间:2014-04-16 20:39:36

标签: c# parsing pop3

从邮箱中检索邮件后,我想将邮件正文与主题,日期和其他信息分开。但我无法找到赖特算法。这是我的代码:

// create an instance of TcpClient 
TcpClient tcpclient = new TcpClient();

// HOST NAME POP SERVER and gmail uses port number 995 for POP 

tcpclient.Connect("pop.gmail.com", 995);
// This is Secure Stream // opened the connection between client and POP Server
System.Net.Security.SslStream sslstream = new SslStream(tcpclient.GetStream());
// authenticate as client  
sslstream.AuthenticateAsClient("pop.gmail.com");
//bool flag = sslstream.IsAuthenticated;   // check flag
// Asssigned the writer to stream 
System.IO.StreamWriter sw = new StreamWriter(sslstream);
// Assigned reader to stream
System.IO.StreamReader reader = new StreamReader(sslstream);
// refer POP rfc command, there very few around 6-9 command
sw.WriteLine("USER my_login");
// sent to server
sw.Flush();
sw.WriteLine("PASS my_pass");
sw.Flush();
// this will retrive your first email
sw.WriteLine("RETR 1");
sw.Flush();

string str = string.Empty;
string strTemp = string.Empty;
while ((strTemp = reader.ReadLine()) != null)
{
    // find the . character in line
    if (strTemp == ".")
    {
        break;
    }
    if (strTemp.IndexOf("-ERR") != -1)
    {
        break;
    }
    str += strTemp;
}

// close the connection
sw.WriteLine("Quit ");
sw.Flush();

richTextBox2.Text = str;

我必须提取:

  • 消息主题
  • 作者
  • 日期
  • 邮件正文

谁能告诉我怎么做?

我收到的字符串(str)包含主题Test message和正文This is the text of test message。它看起来像:

  

+确定Gpop已准备好接受来自46.55.3.85 s42mb37199022eev的请求+确定发送PASS + OK欢迎。+ OK消息followReturn-Path:   收到:来自TMD-I31S3H51L29   (host-static-46-55-3-85.moldtelecom.md。[46.55.3.85])by   mx.google.com with ESMTPSA id o5sm61119999eeg.8.2014.04.16.13.48.20
  for(version = TLSv1   密码= ECDHE-RSA-AES128-SHA位= 128/128); 2014年4月16日星期三   13:48:21 -0700(PDT)消息ID:   < 534eec95.856b0e0a.55e1.6612@mx.google.com> MIME-Version:1.0From:   mail_address@gmail.comTo:mail_address@gmail.com日期:2014年4月16日星期三   13:48:21 -0700(PDT)主题:测试messageContent-Type:text / plain;   charset = us-asciiContent-Transfer-Encoding:quoted-printableThis是   测试信息的文本

非常感谢!

2 个答案:

答案 0 :(得分:0)

String.Split对于此任务来说不够强大。你必须使用正则表达式。我建议的模式是:

^(?<name>\w+): (?<value>.*?)$

意思是:

^                    Beginning of line (if you use the multiline option).
(?<name>pattern)   Capturing group where the group name is "name".
\w+                  A word.
.*?                  Any sequence of characters (for the value)
$                    End of line

此代码......

MatchCollection matches = 
    Regex.Matches(text, @"^(?<name>\w+): (?<value>.*?)$", RegexOptions.Multiline);
foreach (Match match in matches) {
    Console.WriteLine("{0} = {1}", 
        match.Groups["name"].Value, 
        match.Groups["value"].Value
    );
}

...产生这个输出:

  

收到=来自TMD-I31S3H51L29(host-static-46-55-3-85.m ...
  来自= mail_address@gmail.com
  To = mail_address@gmail.com
  日期=星期三,2014年4月16日13:48:21 -0700(PDT)
  主题=测试消息

主体似乎是在“Content-Transfer-Encoding:”行之后开始并转到字符串的末尾。你可以找到这样的身体:

Match body = 
    Regex.Match(text, @"^Content-Transfer-Encoding: .*?$", RegexOptions.Multiline);
if (body.Success) {
    Console.WriteLine(text.Substring(body.Index + body.Length + 1));
}

如果行被LineFeeds分隔,则RegexOptions.Multiline可能无法正常工作。然后,你必须在正则表达式中用^替换行符号的开头和结尾($\n)。

答案 1 :(得分:0)

首先需要阅读rfc1939以了解POP3协议。但阅读完之后,您需要立即阅读以下RFC列表...实际上,请将其搞定,我不会在这里粘贴它们的长列表,我只是链接你到我的MimeKit图书馆的网站上已经有了一个相当易于理解的列表。

正如您的原始代码所做的那样,它需要继续从套接字读取,直到遇到终止序列(&#34;。\ r \ n&#34;),从而终止消息流。

你这样做的方式实在是效率低下,但无论如何,除了你需要撤消POP3服务器完成的任何/所有字节填充以实现线路之外,它(大多数情况下)都能正常工作以句号开头(&#39;。&#39;)。有关更多详细信息,请阅读我上面链接的POP3规范。

要解析标题,您需要阅读rfc822。可以这么说,奥利维尔的方法将会落在他的脸上,很可能是第二次尝试分裂的方法。任何现实世界的信息......除非它非常幸运。

作为提示,邮件正文通过空行与标题分隔。

以下是您可能最终遇到的其他一些问题:

  1. 如果标头值包含非ASCII文本,则应对其进行编码(有关详细信息,请参阅rfc2047rfc2231)。
  2. 野外are not properly encoded中的某些标头值,有时即使它们不应该包含未声明的8位文本。处理这个问题并非易事。这也意味着您不能真正使用StreamReader读取行,因为您将丢失原始字节序列。
  3. 如果您真的想对邮件正文做任何事情,那么您必须编写一个MIME解析器。
  4. 我强烈建议您使用MimeKit和我的其他库MailKit来支持POP3。

    相信我,你正试图以尝试这样做的方式做一个痛苦的世界。