正则表达式以验证SMTP响应 [英] Regex to validate SMTP Responses
问题描述
一旦 SMTP对话框已完成 ,它应传递以下正则表达式(添加了一些括号以提高可读性):
I'm writing a regular expression that can interactively validate SMTP responses codes, once the SMTP dialog is completed it should pass the following regex (some parentheses added for better readability):
^(220)(250){3,}(354)(250)(221)$
或通过( out )身份验证:
^(220)(250)((334){2}(235))?(250){2,}(354)(250)(221)$
我正在尝试重写上述正则表达式,以便可以交互式检查对话框是否按预期进行,否则请礼貌地发送QUIT
命令并关闭连接以节省带宽和时间,但我很难编写出最佳的正则表达式.到目前为止,我已经提出了:
I'm trying to do rewrite the above regexes so that I can interactively check if the dialog is going as expected, otherwise politely send a QUIT
command and close the connection saving bandwidth and time, but I'm having a hard time writing an optimal regex. So far I've managed to come up with:
^(220(250(334(235(250(354(250(221)?)?)?){0,})?){0,2})?)?$
除了仅匹配经过身份验证的连接之外,还有一些错误……例如,它匹配:
Which, besides only matching authenticated connections, has some bugs... For instance, it matches:
220250334235250354250221
220250334334235250354250221
我还尝试了以下修改:
^(220(250)?)?((334(235)?){2})?(250(354(250(221)?)?)?){0,}$
此人接受未经身份验证的响应,但无法匹配220250334
并错误地匹配了220250334334235250354250221
(在354
响应代码之前至少需要2个250
).
This one accepts non-authenticated responses but it fails to match 220250334
and wrongly matches 220250334334235250354250221
(at least 2 250
are needed before the 354
response code).
有人可以帮我这个忙吗?预先感谢.
Can someone help me out with this? Thanks in advance.
我要做的事的例子:
$smtp = fsockopen('mail.example.com', 25);
$result = null;
$commands = array('HELO', 'AUTH LOGIN', 'user', 'pass', 'MAIL FROM', 'RCPT TO', 'RCPT TO', 'DATA', "\r\n.", 'QUIT');
foreach ($commands as $command)
{
$result .= substr(fgets($smtp), 0, 3);
if (preg_match('~^(220(250)?)?((334){1,2}(235)?)?(250(354(250(221)?)?)?){0,}$~S', $result) > 0)
{
fwrite($smtp, $command . "\r\n");
}
else
{
fwrite($smtp, "QUIT\r\n");
fclose($smtp);
break;
}
}
应替换以下程序代码:
$smtp = fsockopen('mail.example.com', 25);
$result = substr(fgets($smtp), 0, 3); // 220
if ($result == '220')
{
fwrite($smtp, 'HELO' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 220
if ($result == '250')
{
fwrite($smtp, 'AUTH LOGIN' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 334
if ($result == '334')
{
fwrite($smtp, 'user' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 334
if ($result == '334')
{
fwrite($smtp, 'pass' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 235
if ($result == '235')
{
fwrite($smtp, 'MAIL FROM' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 250
if ($result == '250')
{
foreach ($to as $mail)
{
fwrite($smtp, 'RCPT TO' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 250
if ($result != '250')
{
fwrite($smtp, 'QUIT' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 221
fclose($smtp);
break;
}
}
if ($result == '250')
{
fwrite($smtp, 'DATA' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 354
if ($result == '354')
{
fwrite($smtp, "\r\n.\r\n");
$result = substr(fgets($smtp), 0, 3); // 250
if ($result == '250')
{
fwrite($smtp, 'QUIT' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 221
fclose($smtp);
if ($result == '221')
{
echo 'SUCESS!';
}
}
else
{
fwrite($smtp, 'QUIT' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 221
fclose($smtp);
}
}
else
{
fwrite($smtp, 'QUIT' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 221
fclose($smtp);
}
}
}
else
{
fwrite($smtp, 'QUIT' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 221
fclose($smtp);
}
}
else
{
fwrite($smtp, 'QUIT' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 221
fclose($smtp);
}
}
else
{
fwrite($smtp, 'QUIT' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 221
fclose($smtp);
}
}
else
{
fwrite($smtp, 'QUIT' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 221
fclose($smtp);
}
}
else
{
fwrite($smtp, 'QUIT' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 221
fclose($smtp);
}
}
else
{
fwrite($smtp, 'QUIT' . "\r\n");
$result = substr(fgets($smtp), 0, 3); // 221
fclose($smtp);
}
推荐答案
令人惊奇的是,经过一整夜的睡眠后,正则表达式变得如此简单.
It's amazing how regular expressions become so much easier after a good night of sleep, here it is:
(?>220(?>250(?>(?>334){1,2}(?>235)?)?(?>(?>250){1,}(?>354(?>250(?>221)?)?)?)?)?)?
可以简化为:
^220(?>250(?>(?>334){1,2}(?>235)?)?(?>(?>250){1,}(?>354(?>250)?)?)?)?$
由于第一个响应代码(220)不是可选的,我们将始终发送最后一个QUIT
命令.
Since the first response code (220) is not optional and we will always send the last QUIT
command.
这篇关于正则表达式以验证SMTP响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!