解析电子邮件标题的最小程序是什么?

时间:2008-12-16 21:08:37

标签: perl email header

作业:http://www.cs.rit.edu/~waw/networks/prob1.082.html

好的,我仍然很困惑为什么这个问题要求我的数据通信和网络课程,但这是我的作业中的问题:

  
      
  1. 编写一个计算机程序,读取电子邮件中的标题和   删除除那些之外的所有行   

    开头      

    From:,To:,Subject:and Cc:。

  2.         

    竞赛 - 谁能写出最短的   这样做的程序。

因此,在考虑了一下之后,我决定使用以下Perl代码尽可能小。

#!/usr/bin/perl

while (<>) { print "$_" if ($_ =~ m/^(To:|From:|Subject:|Cc:)/); }

所有这一切都像一个过滤器,唯一的输出是以From:,To:,Subject:和Cc:开头的行,如问题中所指定的那样。由于没有任何具体细节,我认为上述代码至少可以正确回答问题。

现在,我想知道一个程序可能为此写得多么小?我可以理解,如果没有人想发布代码,因为他们认为我会将它用于作业,但我或多或少都在寻找可以帮助我编写最短程序的建议和技巧。

另外,我确信最短的是指实际的代码长度。他确实提到脚本语言是要走的路,所以我怀疑他正在考虑解释器所涉及的开销。这也意味着他不关心使用哪种语言。

感谢您的期待!

编辑:感谢您的建议!我在这里读了很长一段时间的问题,希望将来我能做出更多贡献。另外,我将Perl代码减少到55个字节的一些建议。我认为我们不需要处理类似多行标题的内容。

奖励:谁能找到一个很好的理由,为什么在我们讨论分组交换和客户端/服务器架构等问题的课程中提出这个问题?

EDIT2:为了记录,我的教授说有人用55字节这样做了。我认为可能的唯一方法是,他只是要求像上面那样简单的实现。

4 个答案:

答案 0 :(得分:10)

一些提示:

  • print "$_"等于print
  • while(&lt;&gt;){...}可以通过在#!行/
  • 上添加-n来替换
  • $ _ = ~m //等于//
  • 您正在键入四个:,其中一个足够好。

这样的东西
#!/usr/bin/perl -n
print if /^(To|From|Subject|Cc):/;

答案 1 :(得分:6)

好的,这是一个多行匹配程序:

$/="";$_=<>;print$&while/^(To|From|Subject|Cc):.*\n( .*\n)*/mg

你想短,不漂亮,对吧; - )

答案 2 :(得分:3)

为什么要先尝试最短可能的程序?从正确的解决方案开始,然后将其编辑为您无法再删除。语法和输入不会成为正确解决方案的瓶颈。即使你的节目比其他任何人都长,如果你是唯一一个正确做到的人,你仍然会获胜。 :)

阅读RFC 2822, "Internet Message Format",了解您需要处理的内容。

然后,查看已经存在的现有电子邮件解析库,以查看他们必须处理的恶作剧。一旦你认为你有一个解决方案因为你遵循RFC,就开始处理所有破碎的邮件。

如果您只是想完成工作,请使用正确的工具。如果您只想播放消息,这是formail的工作,但是您必须编写将在通过您的网络传递的所有消息上运行的紧密代码,然后qsmtp(MTA的mod_perl)可能会是你想要的。

为什么你必须这样做,教练在你问的时候说了什么?无论是在学校还是在“真正的”工作中,你应养成为任何作业指定所需最终状态和约束的习惯。


这是正确完成任务的正确程序。我有点长,因为我也阅读了来自源的所有电子邮件(几乎可以是任何常见的电子邮件存储格式,如mbox,maildir等),我只从每条消息中提取标题。这只有51个字符:

 formail -s formail -c -XTo: -XFrom: -XCc: <my_inbox

如果您更愿意使用Perl解决方案,以便对输出有更多的控制权,那么也是如此:

#!/usr/bin/perl

use Email::Folder;

my $folder = Email::Folder->new($ARGV[0]);

foreach my $message ( $folder->messages )
    {
    print
        join "\n",
        map {
            my $h = $message->header( $_ );
            defined $h ? "$_: $h " : ();
            } 
        qw(From To Cc);

    print "\n\n";
    }   

答案 3 :(得分:0)

好吧,假设你的标题在一个字符串中,每行一个项目(To:,From:等)名为$ head,那么在Powershell中它将是:

$ head.Split(“`n”)| ?{$ _ -match“[To | From | Subject | Cc]:”}