4

宿題: http://www.cs.rit.edu/~waw/networks/prob1.082.html

わかりました、なぜこの質問が私のデータ通信とネットワークのクラスで聞かれたのかまだ混乱していますが、宿題からの質問は次のとおりです。

  1. 電子メール メッセージのヘッダーを読み取り、で始まる行以外のすべての行を削除するコンピューター プログラムを作成します。

    From:、To:、Subject:、および Cc:。

コンテスト -- これを行う最短のプログラムを誰が書けるか。

そこで、少し考えた後、次の Perl コードはこれを実行できるほど小さいものであると判断しました。

#!/usr/bin/perl

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

これは、質問で指定されているように、From:、To:、Subject:、および Cc: で始まる行のみが出力されるフィルターのように機能するだけです。具体的な詳細がないため、上記のコードは少なくとも質問に正しく答えるために機能すると思います。

さて、このためにどれだけ小さなプログラムを書けるだろうか? 誰もコードを投稿したくないのは理解できますが、それは私が課題に使用すると思われるためです。しかし、可能な限り短いプログラムを作成するのに役立つ提案やテクニックを多かれ少なかれ探しています。

また、最短で彼が実際のコード長を指していると確信しています。彼はスクリプト言語が進むべき道であると述べていたので、インタープリターに伴うオーバーヘッドのようなものを彼が考えているとは思えません。これはまた、彼がどの言語が使用されているかを気にしないことを意味します。

ご覧いただきありがとうございます。

編集:提案をありがとう!ここでかなり長い間質問を読んでいましたが、将来的にはもっと貢献できることを願っています。また、Perl コードを 55 バイトに削減した提案もいくつかあります。複数行のヘッダーのようなものを扱う必要はないと思います。

おまけ: パケット交換やクライアント/サーバー アーキテクチャなどについて議論しているクラスで、なぜこれが質問されたのか、正当な理由を誰が特定できますか?

EDIT2:記録のために、私の教授は、誰かが55バイトのようなものでこれを行ったと言いました。それが可能であると私が考える唯一の方法は、彼が上記のような単純な実装のみを求めていた場合です。

4

4 に答える 4

10

いくつかのヒント:

  • print "$_"に等しいprint
  • while(<>) {...} は、#!行のオプションに -n を追加することで置き換えることができます /
  • $_ =~ m// は // に等しい
  • :1つで十分なところに4つ入力しています。

何かのようなもの

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

OK、これが複数行のマッチングプログラムです:

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

あなたは短く、きれいではなく、正しく欲しかったです;-)

于 2008-12-16T22:59:27.203 に答える
3

最初にできるだけ短いプログラムを取得しようとするのはなぜですか? 正しい解決策から始めて、これ以上削除できないように編集します。構文と入力が正しい解決策のボトルネックになることはありません。あなたのプログラムが他の誰よりも長くても、それを正しく実行できたのがあなただけであれば、あなたの勝ちです。:)

RFC 2822「インターネット メッセージ フォーマット」を読んで、何を処理する必要があるかを確認してください。

次に、既存の電子メール解析ライブラリを調べて、処理しなければならない悪ふざけを確認します。RFC に従っているので解決策があると思ったら、壊れたすべてのメーラーに取り組み始めます。

仕事を終わらせようとしているだけなら、適切なツールを使用してください。メッセージをいじりたいだけの場合、これは formail の仕事ですが、ネットワークを通過するすべてのメッセージで実行されるタイトなコードを書かなければならない場合は、qsmtp (MTA の mod_perl) のようなものが必要になるかもしれません。 .

なぜこれをしなければならないのか、インストラクターはあなたが尋ねたときに何と言いましたか? 学校であろうと「実際の」仕事であろうと、課題に対して望ましい最終状態と制約を指定する習慣を身に付ける必要があります。


これは、タスクを正しく完了するための適切なプログラムです。ソース (mbox、maildir など、ほぼすべての一般的な電子メール ストレージ形式) からすべての電子メールも読み取り、各メッセージからヘッダーのみを抽出するため、私のコードは少し長くなります。これはわずか 51 文字です。

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

出力をもう少し制御できるように Perl ソリューションが必要な場合は、こちらもご覧ください。

#!/usr/bin/perl

メール::フォルダーを使用します。

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

foreach my $message ( $folder->messages )
    {
    印刷する
        "\n" に参加し、
        マップ {
            私の $h = $message->header( $_ );
            $h を定義しましたか? "$_: $h" : ();
            }
        qw(From To Cc);

    "\n\n" を印刷します。
    }   
于 2008-12-16T22:25:24.247 に答える
0

$head という名前の行ごとに 1 つの項目 (To:、From: など) を持つ文字列にヘッダーがあると仮定すると、Powershell では次のようになります。

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

于 2008-12-16T21:19:22.147 に答える