C#でRegexを使用した電子メールヘッダーを解析する
-
24-10-2019 - |
質問
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
私は運がなくて一日中、正規表現に苦労しています。
解決
ここの投稿のいくつかに反して、私はMmutzに同意しなければなりません、あなたは正規表現で電子メールを解析することはできません...この記事を参照してください:
http://tools.ietf.org/html/rfc2822#section-3.4.1
3.4.1。 addr-spec仕様
ADDR-Specは、ローカルで解釈された文字列を含む特定のインターネット識別子であり、その後にAT-SIGN文字( "@"、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
他のヒント
RFC 2822に準拠した電子メールRegexは次のとおりです。
(?:[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])+)\])
テキストの上に実行するだけで、メールアドレスが表示されます。
もちろん、Regexが最良のオプションではない場合、Regexを使用しないというオプションが常にあります。しかし、あなた次第です!
RFC2822メールを解析するために正規表現を使用することはできません。その文法には再帰的な生産が含まれているためです(私の頭の上から、コメント用でした (a (nested) comment)
)これは文法を非正規にします。正規表現(名前が示唆するように)は解析することができます 通常 文法。
参照してください XHTMLの自己完結型タグを除くRegexは、オープンタグを一致させます 詳細については。
Blindyが示唆するように、時には昔ながらの方法でそれを解析することができます。
あなたがそれをしたいなら、メールヘッダーのテキストが「ヘッダー」と呼ばれると仮定して、ここに簡単なアプローチがあります。
int start = header.IndexOf("To: ");
int end = header.IndexOf("Cc: ");
string x = header.Substring(start, end-start);
私は減算のバイトでオフになっているかもしれませんが、これを非常に簡単にテストして変更できます。もちろん、あなたは常にあなたのヘッダーにCC:行があるか、これが機能しないことを確認する必要があります。
Regexを使用した電子メールを検証する内訳があります ここ, 、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
, 、それはそれをします。