4

the homework: http://www.cs.rit.edu/~waw/networks/prob1.082.html

Ok, I am still confused why this question was asked for my data communications and networks class, but here is the question from my homework:

  1. Write a computer program that reads the header on an e-mail message and deletes all lines except those that begin with

    From:, To:, Subject: and Cc:.

CONTEST -- Who can write the shortest program that does this.

So after thinking for a bit I decided that the following Perl code was as small as I could do this.

#!/usr/bin/perl

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

All this does is act like a filter for which the only output is lines that start with From:, To:, Subject: and Cc: as specified in the question. Since there aren't any specific details I think that the above code works to at least correctly answer the question.

Now, I wonder how small a program could possibly written for this? I can understand if no one wants to post code because they think I will use it for the assignment, but I am more or less looking for suggestions and techniques that could help me write the shortest program possible.

Also, I am quite sure by shortest he is referring to actual code length. He did mention that scripting languages were the way to go so I doubt he is considering something like the overhead involved with an interpreter. This also means that he does not care which language is used.

Thanks for looking!

EDIT: Thanks for the suggestions! I had been reading questions here for quite a while, hopefully in the future I can contribute more. Also, some of the suggestions I trimmed my Perl code down to 55 bytes. I don't think we will need to deal with something like a multi-line header.

BONUS: Who can identify a good reason why this was asked in a class where we are discussing things like packet switching and client/server architectures?

EDIT2: For the record, my professor said that someone did this with something like 55 bytes. The only way I see that as being possible is if he was only asking for a simple implementation like the one above.

4

4 回答 4

10

一些提示:

  • print "$_"等于print
  • while(<>) {...} 可以通过将 -n 添加到该#!行的选项来替换/
  • $_ =~ m// 等于 //
  • 您正在输入四个:,其中一个就足够了。

就像是

#!/usr/bin/perl -n
print if /^(To|From|Subject|Cc):/;
于 2008-12-16T21:18:59.997 回答
6

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

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

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

于 2008-12-16T22:59:27.203 回答
3

你为什么要首先获得最短的程序?从正确的解决方案开始,然后将其编辑为您无法再删除。语法和类型不会成为正确解决方案的瓶颈。即使你的程序比其他人的程序长,如果你是唯一一个做对的人,你仍然会赢。:)

阅读RFC 2822,“Internet 消息格式”以了解您必须处理的内容。

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

如果您只是想完成工作,请使用正确的工具。如果您只想处理消息,这是 formail 的工作,但是您必须编写紧凑的代码来运行通过您的网络的所有消息,然后像qsmtp(MTA 的 mod_perl)之类的东西可能就是您想要的.

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


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

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

如果您希望有一个 Perl 解决方案,以便对输出有更多的控制,这也是:

#!/usr/bin/perl

使用电子邮件::文件夹;

我的 $folder = 电子邮件::文件夹->new($ARGV[0]);

foreach 我的 $message ( $folder->messages )
    {
    打印
        加入“\n”,
        地图 {
            我的 $h = $message->header( $_ );
            定义 $h ? "$_: $h" : ();
            }
        qw(从到抄送);

    打印“\n\n”;
    }   
于 2008-12-16T22:25:24.247 回答
0

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

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

于 2008-12-16T21:19:22.147 回答