Пару-тройку раз столкнувшись с проблемами, связанными с тем, что в настройках был указан некорректный email-адрес, решил прикрутить какую-нить проверку хотя бы корректности его формата, чтобы по возможности отфильтровывать явный мусор. В результате появилась парочка вспомогательных методов, которые, надеюсь, пригодятся не только мне.
Это добавлено в макрос SysMailer:
X++:
// регулярное выражение для проверки корректности SMTP-адресов
// подсмотрено тут: codeproject.com/Articles/5189/Effective-Email-Address-Validation
// NB! тут специально не использованы ограничители начала и конца строки (^ $)
#localmacro.EmailValidationPattern
@'([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)'
#endmacro
А это пара новых методов в классе SysMailer - собственно проверка корректности формата email-адреса:
X++:
// проверяет email на соответствие нужному формату
#localmacro.Pattern
@'^\s*' + #EmailValidationPattern + @'\s*$'
#endmacro
public static client server boolean isValidEmail(Email _email)
{
boolean ret;
;
if (strlrtrim(_email) != '')
{
new InteropPermission(InteropKind::ClrInterop).assert();
ret = System.Text.RegularExpressions.Regex::IsMatch(_email, #Pattern);
}
return ret;
}
и вспомогательный метод для "выкусывания" email-адреса, если на входе подается строка вида "John Doe <john@somewhere.com>":
X++:
/// <summary>
/// пытается выкинуть из адреса отправителя имя и <>, оставив собственно SMTP-адрес
/// </summary>
/// <param name="_emailFrom">
/// email предположительно в формате "Name <email>"
/// </param>
/// <returns>
/// email без лишней шелухи или же исходную строку, если параметр не подойдет под шаблон
/// </returns>
/// <remarks>
/// в качестве параметра для SMTP-команды MAIL FROM: годится ТОЛЬКО email без всяких там угловых скобок и имен
/// </remarks>
#localmacro.SearchPattern
@'^.+\s<(' + #EmailValidationPattern + @')>$'
#endmacro
#define.ReplacementPattern('$1')
public static client server Email tryRemoveNameFromEmail(Email _emailFrom)
{
System.Text.RegularExpressions.MatchCollection matches;
System.Text.RegularExpressions.Match oneMatch;
Counter nMatches;
Email ret = strlrtrim(_emailFrom);
;
if (ret)
{
new InteropPermission(InteropKind::ClrInterop).assert();
matches = System.Text.RegularExpressions.Regex::Matches(ret, #SearchPattern);
nMatches = matches.get_Count();
if (nMatches > 0)
{
// резать к чертовой матери! не дожидаясь перитонитов...
oneMatch = matches.get_Item(0);
ret = oneMatch.Result(#ReplacementPattern);
}
else
{
ret = _emailFrom;
}
}
return ret;
}