3

Web アプリケーションのフォームへの Webhook 投稿があり、電子メール ヘッダー アドレスを解析する必要があります。

ソーステキストは次のとおりです。

Thread-Topic: test subject
Thread-Index: AcwE4mK6Jj19Hgi0SV6yYKvj2/HJbw==
From: "Lastname, Firstname" <firstname_lastname@domain.com>
To: <testto@domain.com>, testto1@domain.com, testto2@domain.com
Cc: <testcc@domain.com>, test3@domain.com
X-OriginalArrivalTime: 27 Apr 2011 13:52:46.0235 (UTC) FILETIME=[635226B0:01CC04E2]

私は次のものを引き出すことを目指しています:

<testto@domain.com>, testto1@domain.com, testto2@domain.com

私は一日中正規表現に苦労しています。

4

5 に答える 5

6

ここのいくつかの投稿とは対照的に、私は mmutz に同意する必要があります。正規表現でメールを解析することはできません... この記事を参照してください:

https://www.rfc-editor.org/rfc/rfc2822#section-3.4.1

3.4.1. Addr-spec 仕様

addr-spec は、ローカルで解釈された文字列とそれに続くアットマーク文字 (「@」、ASCII 値 64) とそれに続くインターネット ドメインを含む特定のインターネット識別子です。

「ローカルで解釈される」という考えは、受信サーバーだけがそれを解析できると予想されることを意味します。

これを解決しようとすると、「To」行の内容を見つけて分割し、各セグメントを System.Net.Mail.MailAddress で解析しようとします。

    static void Main()
    {
        string input = @"Thread-Topic: test subject
Thread-Index: AcwE4mK6Jj19Hgi0SV6yYKvj2/HJbw==
From: ""Lastname, Firstname"" <firstname_lastname@domain.com>
To: <testto@domain.com>, ""Yes, this is valid""@[emails are hard to parse!], testto1@domain.com, testto2@domain.com
Cc: <testcc@domain.com>, test3@domain.com
X-OriginalArrivalTime: 27 Apr 2011 13:52:46.0235 (UTC) FILETIME=[635226B0:01CC04E2]";

        Regex toline = new Regex(@"(?im-:^To\s*:\s*(?<to>.*)$)");
        string to = toline.Match(input).Groups["to"].Value;

        int from = 0;
        int pos = 0;
        int found;
        string test;
        
        while(from < to.Length)
        {
            found = (found = to.IndexOf(',', from)) > 0 ? found : to.Length;
            from = found + 1;
            test = to.Substring(pos, found - pos);

            try
            {
                System.Net.Mail.MailAddress addy = new System.Net.Mail.MailAddress(test.Trim());
                Console.WriteLine(addy.Address);
                pos = found + 1;
            }
            catch (FormatException)
            {
            }
        }
    }

上記のプログラムからの出力:

testto@domain.com
"Yes, this is valid"@[emails are hard to parse!]
testto1@domain.com
testto2@domain.com
于 2011-04-27T17:16:25.980 に答える
2

RFC 2822 準拠の電子メール正規表現は次のとおりです。

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

テキスト上で実行するだけで、メールアドレスを取得できます。

もちろん、正規表現が最適なオプションではない場合、正規表現を使用しないオプションが常にあります。しかし、あなた次第です!

于 2011-04-27T15:33:34.413 に答える
0

正規表現を使用した電子メールの検証の内訳がここにあり、RFC 2822 のより実用的な実装を参照しています。

[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?

また、「To」フィールドからメールアドレスだけを除外したいようで、<> も気にする必要があるため、次のようなものがうまくいく可能性があります。

^To: ((?:\<?[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\>?,?(?:\s*))*)

繰り返しますが、他の人が述べたように、これをやりたくないかもしれません。しかし、その入力を に変換する正規表現が必要な場合は、それで十分です<testto@domain.com>, testto1@domain.com, testto2@domain.com

于 2011-04-27T16:02:08.627 に答える
0

正規表現を使用して RFC2822 メールを解析することはできません。これは、その文法に再帰的な生成が含まれているため (頭のてっぺんから、それはコメント用でした(a (nested) comment))、文法が非正規化されるためです。正規表現 (名前が示すように) は、通常の文法のみを解析できます。

詳細については、 XHTML 自己完結型タグを除く RegEx マッチ オープン タグも参照してください。

于 2011-04-27T15:48:54.017 に答える
0

Blindy が示唆しているように、昔ながらの方法で解析できる場合もあります。

これを行う場合は、メール ヘッダー テキストが「ヘッダー」と呼ばれると仮定した場合の簡単な方法を次に示します。

int start = header.IndexOf("To: ");
int end = header.IndexOf("Cc: ");
string x = header.Substring(start, end-start);

減算では 1 バイトずれている可能性がありますが、これは非常に簡単にテストおよび変更できます。もちろん、ヘッダーに常に Cc: 行があることを確認する必要があります。そうしないと、これは機能しません。

于 2011-04-27T15:49:14.600 に答える