C # код для подтверждения адреса электронной почты


462

Какой самый элегантный код для проверки того, что строка является действительным адресом электронной почты?



9
Взгляните на статью Фила Хаака: « Я знал, как
проверять

Есть много других важных проверок, а не только строка, лучше проверить, существует ли электронная почта на этом SMTP-сервере или пользователь вводит какую-либо электронную почту и т. д. или использовать API, который будет обрабатывать это, чтобы вы были уверены, что электронная почта правильно, как ver-email.com
Амр Магди


Вы можете использовать библиотеку github.com/jstedfast/EmailValidation .
Мохаммад Реза Садреддини

Ответы:


784

Что насчет этого?

bool IsValidEmail(string email)
{
    try {
        var addr = new System.Net.Mail.MailAddress(email);
        return addr.Address == email;
    }
    catch {
        return false;
    }
}

Чтобы уточнить, вопрос заключается в том, является ли конкретная строка действительным представлением адреса электронной почты, а не является ли адрес электронной почты допустимым местом назначения для отправки сообщения. Для этого единственный реальный способ - отправить сообщение для подтверждения.

Обратите внимание, что адреса электронной почты более простительны, чем вы можете себе представить. Это все совершенно правильные формы:

  • зубчатое колесо
  • "зубчатое колесо апельсина" @ example.com
  • 123@$.xyz

В большинстве случаев ложное «недействительное» гораздо хуже для ваших пользователей и проверки в будущем, чем ложное «действительное». Вот статья, которая раньше была принятым ответом на этот вопрос (этот ответ с тех пор был удален). В нем есть гораздо больше деталей и некоторые другие идеи о том, как решить проблему.

Обеспечение проверок работоспособности - все еще хорошая идея для пользовательского опыта. Предполагая, что адрес электронной почты действителен, вы можете искать известные домены верхнего уровня, проверять домен на наличие записи MX, проверять орфографические ошибки из общих доменных имен (gmail.cmo) и т. Д. Затем представить предупреждение, дающее пользователю возможность сказать «да, мой почтовый сервер действительно позволяет 🌮🍳🎁 в качестве адреса электронной почты».


Что касается использования обработки исключений для бизнес-логики, я согласен, что этого следует избегать. Но это один из тех случаев, когда удобство и ясность могут перевесить догму.

Кроме того, если вы делаете что-либо еще с адресом электронной почты, возможно, потребуется включить его в адрес электронной почты. Даже если вы не используете эту точную функцию, вы, вероятно, захотите использовать тот же шаблон. Вы также можете проверить наличие определенных типов сбоев, перехватывая различные исключения : пустой, пустой или неверный формат.


Согласно комментарию Стюарта, это сравнивает конечный адрес с исходной строкой, а не всегда возвращает true. MailAddress пытается проанализировать строку с пробелами в части «Отображаемое имя» и «Адрес», поэтому исходная версия возвращала ложные срабатывания.


--- Дальнейшее чтение ---

Документация для System.Net.Mail.MailAddress

Объяснение того, что составляет действительный адрес электронной почты


23
На самом деле, это не так. @ @ является действительным адресом электронной почты. См. Haacked.com/archive/2007/08/21/… На самом деле этот метод возвращает неверные результаты, если вы используете адрес с кавычками.
шестерня

53
+1: это лучший ответ, если вы используете System.Net.Mailклассы для отправки почты, что вы, вероятно, используете, если вы используете .NET. Мы приняли решение использовать этот тип проверки просто потому, что нет смысла принимать адреса электронной почты, даже действительные, на которые мы не можем отправлять почту.
Грег Бич

24
Я не рекомендую Возвращает истину:IsValidEmail("this is not valid@email$com");
Какаши

15
Многие проблемы, по-видимому, заключаются в том, что MailAddress пытается также проанализировать DisplayName, поэтому «single space@domain.com» анализирует для DisplayName «single» и Address «space@domain.com». Для решения этой проблемы необходимо: return (addr.Address == email);
Стюарт

18
Мне это нравится; Я не считаю принуждение более строгим, чем действительная спецификация. Ложные негативы намного хуже ложных («что ты имеешь в виду, моя электронная почта недействительна? »)
Кейси

242

Это старый вопрос, но все ответы, которые я нашел на SO, включая более недавние, отвечают аналогично этому. Однако в .Net 4.5 / MVC 4 вы можете добавить проверку формы электронного адреса в форму, добавив аннотацию [EmailAddress] из System.ComponentModel.DataAnnotations, поэтому мне было интересно, почему я не могу просто использовать встроенную функциональность из. Чистая в общем.

Это, кажется, работает, и мне кажется довольно элегантным:

using System.ComponentModel.DataAnnotations;

class ValidateSomeEmails
{
    static void Main(string[] args)
    {
        var foo = new EmailAddressAttribute();
        bool bar;
        bar = foo.IsValid("someone@somewhere.com");         //true
        bar = foo.IsValid("someone@somewhere.co.uk");       //true
        bar = foo.IsValid("someone+tag@somewhere.net");     //true
        bar = foo.IsValid("futureTLD@somewhere.fooo");      //true

        bar = foo.IsValid("fdsa");                          //false
        bar = foo.IsValid("fdsa@");                         //false
        bar = foo.IsValid("fdsa@fdsa");                     //false
        bar = foo.IsValid("fdsa@fdsa.");                    //false

        //one-liner
        if (new EmailAddressAttribute().IsValid("someone@somewhere.com"))
            bar = true;    
    }
}

4
Круто, хотя разочаровывает, что MS не может заставить это согласиться с их собственной документацией . Это отклоняет js@proseware.com9
Кейси

13
Обратите внимание, что EmailAddressAttributeэто менее разрешительно, чем System.Net.Mail.MailAddress- например, MailAddressпринимает адрес для TLD. Просто что-то, что нужно иметь в виду, если вам нужно быть максимально разрешающим.
Ааронин

5
@Cogwheel: если ответ лежит где-то в комментариях, его, вероятно, следует добавить к основному тексту ответа.
hofnarwillie

6
@hofnarwillie: это в основной части, но комментарии тщательно продуманы. Если ваша цель состоит в том, чтобы не злить ваших пользователей, то ваша проверка не должна быть более строгой, чем спецификация. Единственный способ действительно проверить, является ли электронное письмо действительным, - это отправить тестовое сообщение.
зубчатое

4
Обратите внимание, что foo.IsValid(null);возвращается true.
Urig

62

Я использую этот метод с одним вкладышем, который делает работу для меня

using System.ComponentModel.DataAnnotations;
public bool IsValidEmail(string source)
{
    return new EmailAddressAttribute().IsValid(source);
}

Согласно комментариям, это «не получится», если source(адрес электронной почты) является нулевым.

public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);

1
Это не работает для меня; Я получаю: "Аннотации данных" не существует ... Вы пропустили ссылку на сборку? " Какую ссылку мне нужно добавить?
Б. Клэй Шеннон

Это вернет истину, если источник нулевой. См. Msdn.microsoft.com/en-us/library/hh192424 "true, если указанное значение является действительным или пустым; в противном случае - false."
Джао

2
Лучшая версия:public static Boolean IsValidMailAddress(this String pThis) => pThis == null ? false : new EmailAddressAttribute().IsValid(pThis);
Себастьян Хофманн

7
Или еще лучше:public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);
Патрик Меландер

1
Я не думаю, что этот метод расширения должен молча возвращаться falseдля нулевых строк. Вот почему я предлагаю (еще лучше) версию ++ public static bool IsValidEmailAddress(this string address) => new EmailAddressAttribute().IsValid(address ?? throw new ArgumentNullException());. Теперь я пойду и найду реформатскую церковь еще более лучших версионистов.
Marc.2377

41

.net 4.5 добавил System.ComponentModel.DataAnnotations.EmailAddressAttribute

Вы можете просмотреть источник EmailAddressAttribute , это Regex, который он использует внутри:

const string pattern = @"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$";

2
К сожалению, EmaillAddressAttribute разрешает С, который не является допустимым символом для электронной почты
BZ

16
@BZ Да, это так. Почему вы думаете, что нет?
Кейси

@Chad Grant: это версия C #. Можете ли вы предоставить VB.Net один. Потому что это ускользнет от символов-символов, таких как \\ to \, или вы можете предоставить дословную строку.
Нихил Агравал

3
Это работает, но не забывайте, RegexOptions.IgnoreCaseпотому что этот шаблон не позволяет заглавные буквы явно!
Крис

1
Обратите внимание, что Regex очень продуман: «Этот атрибут обеспечивает проверку электронной почты на стороне сервера, эквивалентную jquery validate, и, следовательно, использует одно и то же регулярное выражение».
Охад Шнайдер

38

Я взял ответ Фила из # 1 и создал этот класс. Назовите это так:bool isValid = Validator.EmailIsValid(emailString);

Вот класс:

using System.Text.RegularExpressions;

public static class Validator
{

    static Regex ValidEmailRegex = CreateValidEmailRegex();

    /// <summary>
    /// Taken from http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx
    /// </summary>
    /// <returns></returns>
    private static Regex CreateValidEmailRegex()
    {
        string validEmailPattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
            + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
            + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";

        return new Regex(validEmailPattern, RegexOptions.IgnoreCase);
    }

    internal static bool EmailIsValid(string emailAddress)
    {
        bool isValid = ValidEmailRegex.IsMatch(emailAddress);

        return isValid;
    }
}

5
Просто маленький, но я бы использовал: return (! String.IsNullOrEmpty (emailAddress)) && ValidEmailRegex.IsMatch (emailAddress);
Марк

Это просто ужас :)
Александру Дику

31

Лично я бы сказал, что вы должны убедиться, что там есть символ @, возможно, с. персонаж. Есть много регулярных выражений, которые вы можете использовать с разной корректностью, но я думаю, что большинство из них оставляют действительные адреса электронной почты или пропускают недействительные. Если люди хотят ввести поддельный адрес электронной почты, они введут поддельный. Если вам необходимо убедиться, что адрес электронной почты является законным и этот человек контролирует этот адрес электронной почты, вам необходимо отправить ему письмо со специальной кодированной ссылкой, чтобы они могли убедиться, что это действительно реальный адрес.


6
Я лично думаю, что вы должны сделать немного больше проверки, чем это. Кто-то обязательно попробует адрес электронной почты Бобби Табл или еще хуже.
Люк Куинэйн

31
Что не так с адресом электронной почты таблицы Бобби, если вы используете готовые заявления. Мы говорим о действительных адресах электронной почты, а не о других вещах, которые не имеют ничего общего с тем, что составляет действительный адрес электронной почты, например о том, как правильно выполнять запросы SQL, чтобы у вас не возникало проблем с внедрением SQL.
Кибби

Я предполагаю, что вы не знаете, что кто-то вставит туда, но злоумышленник знает, что в конечном итоге это значение может быть введено в вашу почтовую систему. Я просто предпочел бы пойти глубоко в оборону и быть немного строже.
Люк Куинэйн,

10
Это для почтовой системы беспокоиться. Я не стал бы отказываться от совершенно корректных адресов электронной почты только потому, что это могло быть проблемой безопасности с какой-либо другой системой. Если весь ваш почтовый сервер нуждается в неверно сформированном адресе электронной почты, чтобы вызвать проблемы с безопасностью, вам, вероятно, следует переключиться на другой сервер.
Кибби

4
Глубокая защита работает только в том случае, если каждый уровень вашего лука безопасности не гнилой. Один гнилой слой означает, что вы испортите весь лук. Отказ от «foo@example.com.au», потому что вы хотите защититься от уязвимостей в кодировке µ-закона Sun, не имеет смысла, не так ли? Не смейся, это случилось со мной. Причина, по которой я здесь комментирую, состоит в том, что Medicare Australia не допускает адреса «.au», только «.com». Читайте также Марк Суонсон, «Как не проверять электронную почту», mdswanson.com/blog/2013/10/14/…
ManicDee,

17

Я думаю, что лучший способ заключается в следующем:

    public static bool EmailIsValid(string email)
    {
        string expression = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";

        if (Regex.IsMatch(email, expression))
        {
            if (Regex.Replace(email, expression, string.Empty).Length == 0)
            {
                return true;
            }
        }
        return false;
    }

Вы можете иметь эту статическую функцию в общем классе.


Этот ответ не принимает адрес с TLD в доменной части.
Симона

15

Короткий и точный код

string Email = txtEmail.Text;
if (Email.IsValidEmail())
{
   //use code here 
}

public static bool IsValidEmail(this string email)
{
  string pattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|" + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)" + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";    
  var regex = new Regex(pattern, RegexOptions.IgnoreCase);    
  return regex.IsMatch(email);
}

2
Спасибо за решение
Джек Гаджанан

Мне пришлось изменить публичный статический bool IsValidEmail (это электронное письмо с строкой) на общедоступный статический bool IsValidEmail (электронное письмо с строкой), чтобы избежать ЭТОГО: stackoverflow.com/questions/10412233/…
Goner Doug

@ Гонер Даг, эта функциональность будет работать следующим образом. (Bool flag = EmailAddress.IsValidEmail ())
Naveen

2
«ЭТО» нужно было удалить, чтобы избежать проблем с компилятором при добавлении в мою форму.
Гонер Дуг

@ Гонер Дуг, его функциональность будет работать так. string email = "abc@xyz.com"; if (email.IsValidEmail ()) {return false; } else {return true;}
Навин

14

Самый элегантный способ - использовать встроенные методы .Net.

Эти методы:

  • Испытаны и проверены. Эти методы используются в моих собственных профессиональных проектах.

  • Используйте регулярные выражения внутри, которые являются надежными и быстрыми.

  • Сделано в Microsoft для C #. Нет необходимости изобретать велосипед.

  • Вернуть результат bool. True означает, что электронная почта действительна.

Для пользователей .Net 4.5 и выше

Добавьте эту ссылку в ваш проект:

System.ComponentModel.DataAnnotations

Теперь вы можете использовать следующий код:

(new EmailAddressAttribute().IsValid("youremailhere@test.test"));

Пример использования

Вот несколько способов объявить:

protected List<string> GetRecipients() // Gets recipients from TextBox named `TxtRecipients`
{
    List<string> MethodResult = null;

    try
    {
        List<string> Recipients = TxtRecipients.Text.Replace(",",";").Replace(" ", "").Split(';').ToList();

        List<string> RecipientsCleaned = new List<string>();

        foreach (string Recipient in RecipientsCleaned)
        {
            if (!String.IsNullOrWhiteSpace(Recipient))
            {
                RecipientsNoBlanks.Add(Recipient);

            }

        }

        MethodResult = RecipientsNoBlanks;

    }
    catch//(Exception ex)
    {
        //ex.HandleException();
    }

    return MethodResult;

}


public static bool IsValidEmailAddresses(List<string> recipients)
{
    List<string> InvalidAddresses = GetInvalidEmailAddresses(recipients);

    return InvalidAddresses != null && InvalidAddresses.Count == 0;

}

public static List<string> GetInvalidEmailAddresses(List<string> recipients)
{
    List<string> MethodResult = null;

    try
    {
        List<string> InvalidEmailAddresses = new List<string>();

        foreach (string Recipient in recipients)
        {
            if (!(new EmailAddressAttribute().IsValid(Recipient)) && !InvalidEmailAddresses.Contains(Recipient))
            {
                InvalidEmailAddresses.Add(Recipient);

            }

        }

        MethodResult = InvalidEmailAddresses;

    }
    catch//(Exception ex)
    {
        //ex.HandleException();

    }

    return MethodResult;

}

... и код, демонстрирующий их в действии:

List<string> Recipients = GetRecipients();

bool IsValidEmailAddresses = IsValidEmailAddresses(Recipients);

if (IsValidEmailAddresses)
{
    //Emails are valid. Your code here

}
else
{
    StringBuilder sb = new StringBuilder();

    sb.Append("The following addresses are invalid:");

    List<string> InvalidEmails = GetInvalidEmailAddresses(Recipients);

    foreach (string InvalidEmail in InvalidEmails)
    {
        sb.Append("\n" + InvalidEmail);

    }

    MessageBox.Show(sb.ToString());

}

Кроме того, этот пример:

  • Расширяется за пределы спецификации, так как одна строка содержит 0, один или несколько адресов электронной почты, разделенных точкой с запятой ; .
  • Наглядно демонстрируется, как использовать метод IsValid объекта EmailAddressAttribute.

Альтернатива, для пользователей версии .Net менее 4,5

Для ситуаций, когда .Net 4.5 недоступен, я использую следующее решение:

В частности, я использую:

public static bool IsValidEmailAddress(string emailAddress)
{
    bool MethodResult = false;

    try
    {
        MailAddress m = new MailAddress(emailAddress);

        MethodResult = m.Address == emailAddress;

    }
    catch //(Exception ex)
    {
        //ex.HandleException();

    }

    return MethodResult;

}

public static List<string> GetInvalidEmailAddresses(List<string> recipients)
{
    List<string> MethodResult = null;

    try
    {
        List<string> InvalidEmailAddresses = new List<string>();

        foreach (string Recipient in recipients)
        {
            if (!IsValidEmail(Recipient) && !InvalidEmailAddresses.Contains(Recipient))
            {
                InvalidEmailAddresses.Add(Recipient);

            }

        }

        MethodResult = InvalidEmailAddresses;

    }
    catch //(Exception ex)
    {
        //ex.HandleException();

    }

    return MethodResult;

}

1
@ThomasAyoub Я не видел ответа EmailAddressAttribute, и нет ответа, который использует новый MailAddress () с проверкой ввода == .Address, так что я думаю, что он довольно полезен. Без чтения комментариев принятый ответ довольно неправильный. новый MailAddress ("Foobar Some@thing.com") доказывает это.
Jan

@Jan fwiw, Маник обошел Безрукавку EmailAddressAttributeчуть менее чем за четыре месяца, хотя этот действительно уловил nullпроблему.
ruffin

7

Если честно, в производственном коде лучшее, что я делаю, это проверяю @символ.

Я никогда не в состоянии полностью проверять электронную почту. Вы знаете, как я вижу, было ли это действительно верно? Если это было отправлено. Если это не так, это плохо, если это так, жизнь хороша. Это все, что мне нужно знать.


6

Я нахожу это регулярное выражение хорошим компромиссом между проверкой чего-то большего, чем просто знак @, и принятием странных крайних случаев:

^[^@\s]+@[^@\s]+(\.[^@\s]+)+$

Это, по крайней мере, заставит вас поместить что-то вокруг знака @, и, по крайней мере, поместит домен, который выглядит нормально.


Я придумал такое же регулярное выражение;) Это позволяет использовать недопустимые символы
Stefan

Этот ответ не принимает TLD в доменной части.
Симона

@Simone, вероятно, ни у кого нет адресов электронной почты с TLD в доменной части, хотя на практике: serverfault.com/a/721929/167961 отметьте в комментариях, что это может быть запрещено в эти дни
Мэтью Локк

@ MatthewLock Может ли это быть адресом в интрасети? Как bob@companyinternal?
Симона

@ Симон, кто-нибудь в реальной жизни использует эту схему?
Мэтью Лок

4

Проверка адреса электронной почты не так проста, как может показаться. На самом деле теоретически невозможно полностью проверить адрес электронной почты, используя только регулярное выражение.

Прочтите об этом в моем блоге для обсуждения этой темы и реализации F # с использованием FParsec. [/ shameless_plug]


1
Мне понравился список альтернативных подходов; очень интересно.
Люк Куинэйн

1
Интересная статья. А если серьезно, кто помещает комментарии, и вложенные в это, в адреса электронной почты?
Мэтью Лок

3
@matthew Я не знаю, почему IETF даже допустил это, но это возможно , поэтому тщательная проверка должна принять это во внимание.
Маурисио Шеффер

4

Вот мой ответ - решение Фила не подходит для однобуквенных доменов, таких как "somebody@q.com". Верьте или нет, это используется =) (идет к Centurylink, например).

Ответ Фила также будет работать только со стандартом PCRE ... поэтому C # примет его, но javascript будет бомбить. Это слишком сложно для JavaScript. Таким образом, вы не можете использовать решение Фила для атрибутов проверки mvc.

Вот мое регулярное выражение. Это будет хорошо работать с атрибутами валидации MVC.
- Все до @ упрощено, так что по крайней мере javascript будет работать. Я в порядке, расслабляющая проверка здесь, пока сервер обмена не дает мне 5.1.3. - Все после @ - это решение Фила, измененное для однобуквенных доменов.

public const string EmailPattern =
        @"^\s*[\w\-\+_']+(\.[\w\-\+_']+)*\@[A-Za-z0-9]([\w\.-]*[A-Za-z0-9])?\.[A-Za-z][A-Za-z\.]*[A-Za-z]$";

Для людей, предлагающих использовать system.net.mail MailMessage (), эта возможность ПУТЬ гибкая. Конечно, C # примет электронное письмо, но затем сервер обмена взорвется с ошибкой во время выполнения 5.1.3, как только вы попытаетесь отправить электронное письмо.


это, кажется, лучший самый продуманный / разумный / реальный ответ, спасибо, Ральф!
Толстяк

это лучший ответ на данный момент! Я не могу поверить, что плохое решение, которое принимает basket@ballв качестве действительного адреса электронной почты, получило правильный ответ, а также все эти отрицательные отзывы. Спасибо, в любом случае!
катастрофа

Спасибо, это лучшее решение и должен быть принят ответ.
Bat_Programmer

3

Если вы действительно, и я имею в виду, действительно хотите знать, является ли адрес электронной почты действительным ... попросите почтовый обменник доказать это, никаких регулярных выражений не требуется. Я могу предоставить код, если требуется.

Основные шаги следующие: 1. есть ли в адресе электронной почты часть имени домена? (индекс @> 0) 2. с помощью DNS-запроса спросить, есть ли у домена почтовый обменник 3. открыть tcp-соединение с почтовым обменником 4. с помощью протокола smtp открыть сообщение на сервер, используя адрес электронной почты в качестве получателя 5. разобрать ответ сервера. 6. Закройте сообщение, если вы сделали это далеко, все хорошо.

Это, как вы можете себе представить, очень дорогое время и требует SMTP, но это работает.


Вы создавали подделки, заглушки и / или макеты для этих интерфейсов?
Отметить

1
Это не сработает. Протокол smtp для проверки адреса электронной почты LONG устарел / не используется. Включать это на почтовых серверах считается плохой практикой, поскольку спаммеры используют эту функцию.
Чад Грант

Я буду держать ваше предложение на уровне 2. Способ более перспективен на будущее, чем проверка на известный шаблон доменного имени.
Симона

Выбираешь, а определяешь "почтовый обменник" ? Если нет записей MX, SMTP должен вернуться к записи A / AAAA, согласно RFC2821 / 5321. Если запись MX существует, она все равно может не указывать на наличие почтового обменника (RFC7505). На самом деле, единственный способ - отправить им письмо со ссылкой на призыв к действию и ждать, пока они ответят ...
jimbobmcgee

2

Вообще говоря, регулярное выражение для проверки адресов электронной почты не так легко придумать; на момент написания этой статьи синтаксис адреса электронной почты должен соответствовать относительно большому количеству стандартов, и реализация всех из них в регулярном выражении практически неосуществима!

Я настоятельно рекомендую вам попробовать нашу EmailVerify.NET , зрелую библиотеку .NET, которая может проверять адреса электронной почты после всех текущими стандартами IETF (RFC 1123, RFC 2821, RFC 2822, RFC 3696, RFC 4291, RFC 5321 и RFC 5322). проверяет соответствующие записи DNS, проверяет, могут ли целевые почтовые ящики принимать сообщения и даже может сказать, является ли данный адрес доступным или нет.

Отказ от ответственности: я ведущий разработчик для этого компонента.


Впечатляет! «Затем он пытается связаться с почтовым обменником, ответственным за данный адрес электронной почты, и запускает фиктивный диалог SMTP с этим сервером, эмулируя реальный почтовый сервер. Таким образом, он гарантирует, что сервер может обрабатывать электронные письма для адреса. Многие SMTP-серверы фактически возвращать ложные положительные ответы в качестве защиты от спамеров: чтобы преодолеть эту проблему, EmailVerify для .NET наконец пытается несколько раз запросить целевой почтовый обменник с разными сфабрикованными адресами. "
Мэтью Лок

Спасибо, @MatthewLock;)
Эфран Кобизи

Хорошо, но я вижу только платные издания. Есть ли у вас планы по выпуску сообщества / OpenSource?
Охад Шнайдер

1
@OhadSchneider Да: мы предлагаем бесплатную версию нашей технологии проверки электронной почты посредством Verifalia, нашей службы проверки электронной почты SaaS . Verifalia поставляется с бесплатными SDK с открытым исходным кодом для основных платформ разработки программного обеспечения, включая .NET .
Эфран Кобизи

2
For the simple email like goerge@xxx.com, below code is sufficient. 

 public static bool ValidateEmail(string email)
        {
            System.Text.RegularExpressions.Regex emailRegex = new System.Text.RegularExpressions.Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$");
            System.Text.RegularExpressions.Match emailMatch = emailRegex.Match(email);
            return emailMatch.Success;
        }

Не удастся подтвердить a@b.info как действительный адрес электронной почты.
Рэй Ченг

2

Если вы используете FluentValidation, вы можете написать что-то простое:

public cass User
{
    public string Email { get; set; }
}

public class UserValidator : AbstractValidator<User>
{
    public UserValidator()
    {
        RuleFor(x => x.Email).EmailAddress().WithMessage("The text entered is not a valid email address.");
    }
}

// Validates an user. 
var validationResult = new UserValidator().Validate(new User { Email = "açflkdj" });

// This will return false, since the user email is not valid.
bool userIsValid = validationResult.IsValid;

2

небольшая модификация ответа @Cogwheel

public static bool IsValidEmail(this string email)
{
  // skip the exception & return early if possible
  if (email.IndexOf("@") <= 0) return false;

  try
  {
    var address = new MailAddress(email);
    return address.Address == email;
  }
  catch
  {
    return false;
  }
}

Это, похоже, не помогает ... Console.WriteLine(MailAddress("asdf@asdf.").Address);выводит "asdf @ asdf.", Что недопустимо .
Лэнгдон

.net, похоже, имеет свое собственное определение valid. соответствующее обсуждение
waitforit

2

Здесь много сильных ответов. Однако я рекомендую сделать шаг назад. @Cogwheel отвечает на вопрос https://stackoverflow.com/a/1374644/388267 . Тем не менее, это может быть дорогостоящим в сценарии массовой проверки, если многие из проверяемых адресов электронной почты являются недействительными. Я предлагаю использовать немного логики, прежде чем мы войдем в его блок try-catch. Я знаю, что следующий код может быть написан с использованием RegEx, но это может быть дорого для новых разработчиков. Это моя двойная стоимость:

    public static bool IsEmail(this string input)
    {
        if (string.IsNullOrWhiteSpace(input)) return false;

        // MUST CONTAIN ONE AND ONLY ONE @
        var atCount = input.Count(c => c == '@');
        if (atCount != 1) return false;

        // MUST CONTAIN PERIOD
        if (!input.Contains(".")) return false;

        // @ MUST OCCUR BEFORE LAST PERIOD
        var indexOfAt = input.IndexOf("@", StringComparison.Ordinal);
        var lastIndexOfPeriod = input.LastIndexOf(".", StringComparison.Ordinal);
        var atBeforeLastPeriod = lastIndexOfPeriod > indexOfAt;
        if (!atBeforeLastPeriod) return false;

        // CODE FROM COGWHEEL'S ANSWER: https://stackoverflow.com/a/1374644/388267 
        try
        {
            var addr = new System.Net.Mail.MailAddress(input);
            return addr.Address == input;
        }
        catch
        {
            return false;
        }
    }

2

Ответ с наибольшим количеством голосов от @Cogwheel - лучший ответ, однако я попытался реализовать trim()строковый метод, чтобы он урезал все пробелы пользователя от начала и до конца строки. Проверьте код ниже для полного примера-

bool IsValidEmail(string email)
{
    try
    {
        email = email.Trim();
        var addr = new System.Net.Mail.MailAddress(email);
        return addr.Address == email;
    }
    catch
    {
        return false;
    }
}

Риск этого заключается в том, что вы проверяете адрес электронной почты, отличный от адреса источника, что заставляет вас думать, что вы можете отправить по почте (в данном случае) версию указанного адреса электронной почты без полей. Лучшим подходом было бы создать отдельный метод SanitizeEmail(string email), используя результат этого метода для проверки и отправки электронного письма.
Марко де Зеув

1
private static bool IsValidEmail(string emailAddress)
{
    const string validEmailPattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
                                     + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
                                     + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";

    return new Regex(validEmailPattern, RegexOptions.IgnoreCase).IsMatch(emailAddress);
}

1

Проверьте правильность или неправильность формата электронной почты System.Text.RegularExpressions:

    public static bool IsValidEmailId(string InputEmail)
    {
        Regex regex = new Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$");
        Match match = regex.Match(InputEmail);
        if (match.Success)
            return true;
        else
            return false;
    }

    protected void Email_TextChanged(object sender, EventArgs e)
    {
        String UserEmail = Email.Text;
        if (IsValidEmailId(UserEmail))
        {
            Label4.Text = "This email is correct formate";
        }
        else
        {
            Label4.Text = "This email isn't correct formate";
        }
    }

1

/ Использование внутреннего регулярного выражения, используемого при создании «new EmailAddressAttribute ();»; компонент в .Net4.5 >>> используя System.ComponentModel.DataAnnotations; // Для проверки адреса электронной почты ...... Проверено и работает.

public bool IsEmail(string email)
{
    if (String.IsNullOrEmpty(email))
    {   return false;  }
    try
    {
        Regex _regex = new Regex("^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])" +
                "+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)" +
                "((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|" +
                "[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\u" +
                "FDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|" +
                "(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|" +
                "[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900" +
                "-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFF" +
                "EF])))\\.?$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled);
        return _regex.IsMatch(email);
    }
    catch (RegexMatchTimeoutException)
    {
        return false;
    }
}

Также Вы можете использовать это:

http://msdn.microsoft.com/en-us/library/01escwtf(v=vs.110).aspx


для этого письма он говорит: «fulya_42_@hotmail.coö» и выдает ошибку в mandrill api
MonsterMMORPG

1
Во-первых, адрес электронной почты действителен wrt example@example.co или example@example.com .... В письме содержатся все допустимые строки и критерии, кроме последнего символа «ö», и вы можете легко добавить простое условие для проверки такого символа , Во-вторых, я не уверен насчет этой ошибки API Mandrill, возможно, вы захотите проверить свой метод использования. Я использовал эту проверку в некоторых других средах / API, и это было хорошо для меня.
Айна Адемола C

1

Я обобщил ответ Пойсона 1 так:

public static bool IsValidEmailAddress(string candidateEmailAddr)
{
    string regexExpresion = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
    return (Regex.IsMatch(candidateEmailAddr, regexExpresion)) && 
           (Regex.Replace(candidateEmailAddr, regexExpresion, string.Empty).Length == 0);
}

1

Простой способ идентифицировать emailid действителен или нет.

public static bool EmailIsValid(string email)
{
        return Regex.IsMatch(email, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
}

1

Существует проблема культуры в регулярных выражениях в C #, а не в js. Поэтому нам нужно использовать регулярные выражения в режиме США для проверки электронной почты. Если вы не используете режим ECMAScript, ваши специальные языковые символы обозначаются в AZ с регулярным выражением.

Regex.IsMatch(email, @"^([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})(\]?)$", RegexOptions.ECMAScript)

1

В итоге я использовал это регулярное выражение, поскольку оно успешно проверяет запятые, комментарии, символы Юникода и доменные адреса IP (v4).

Действительные адреса будут:

"" @ example.org

(comment)test@example.org

тест@example.org

ტესტი @ example.org

тест @ [192.168.1.1]

 public const string REGEX_EMAIL = @"^(((\([\w!#$%&'*+\/=?^_`{|}~-]*\))?[^<>()[\]\\.,;:\s@\""]+(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))(\([\w!#$%&'*+\/=?^_`{|}~-]*\))?@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$";

1

Простой без использования Regex (который мне не нравится из-за плохой читаемости):

bool IsValidEmail(string email)
{
    string emailTrimed = email.Trim();

    if (!string.IsNullOrEmpty(emailTrimed))
    {
        bool hasWhitespace = emailTrimed.Contains(" ");

        int indexOfAtSign = emailTrimed.LastIndexOf('@');

        if (indexOfAtSign > 0 && !hasWhitespace)
        {
            string afterAtSign = emailTrimed.Substring(indexOfAtSign + 1);

            int indexOfDotAfterAtSign = afterAtSign.LastIndexOf('.');

            if (indexOfDotAfterAtSign > 0 && afterAtSign.Substring(indexOfDotAfterAtSign).Length > 1)
                return true;
        }
    }

    return false;
}

Примеры:

  • IsValidEmail("@b.com") // false
  • IsValidEmail("a@.com") // false
  • IsValidEmail("a@bcom") // false
  • IsValidEmail("a.b@com") // false
  • IsValidEmail("a@b.") // false
  • IsValidEmail("a b@c.com") // false
  • IsValidEmail("a@b c.com") // false
  • IsValidEmail("a@b.com") // true
  • IsValidEmail("a@b.c.com") // true
  • IsValidEmail("a+b@c.com") // true
  • IsValidEmail("a@123.45.67.89") // true

Он должен быть простым и поэтому не касается редких случаев, таких как электронные письма с доменами в квадратных скобках, которые содержат пробелы (как правило, разрешены), электронные письма с адресами IPv6 и т. Д.


1

Вот ответ на ваш вопрос для вас, чтобы проверить.

using System;
using System.Globalization;
using System.Text.RegularExpressions;

public class RegexUtilities
{    
   public bool IsValidEmail(string strIn)
   {
       if (String.IsNullOrEmpty(strIn))
       {
          return false;

       }

       // Use IdnMapping class to convert Unicode domain names.

       try 
       {
          strIn = Regex.Replace(strIn, @"(@)(.+)$", this.DomainMapper, RegexOptions.None, TimeSpan.FromMilliseconds(200));

       }
       catch (RegexMatchTimeoutException) 
       {
           return false;

       }

       if (invalid)
       {
           return false;

       }

       // Return true if strIn is in valid e-mail format.    

       try 
       {
          return Regex.IsMatch(strIn, @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|       [-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));

       }
       catch (RegexMatchTimeoutException) 
       {
          return false;

       }

   }


   private string DomainMapper(Match match)
   {
      // IdnMapping class with default property values.

      IdnMapping idn = new IdnMapping();

      string domainName = match.Groups[2].Value;

      try 
      {
         domainName = idn.GetAscii(domainName);

      }
      catch (ArgumentException) 
      {
         invalid = true;

      }

      return match.Groups[1].Value + domainName;

   }

}

1

Основываясь на ответе @Cogwheel, я хочу поделиться модифицированным решением, которое работает для SSIS и «Компонент скрипта»:

  1. Поместите «Компонент скрипта» в ваше соединение потока данных, а затем откройте его.
  2. В разделе «Столбцы ввода» установите для поля, содержащего адреса электронной почты, значение «ReadWrite» (в примере «fieldName»).
  3. Вернитесь в раздел «Сценарий» и нажмите «Редактировать сценарий». Тогда вам нужно подождать после открытия кода.
  4. Поместите этот код в правильный метод:

    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        string email = Row.fieldName;
    
        try
        {
            System.Net.Mail.MailAddress addr = new System.Net.Mail.MailAddress(email);
            Row.fieldName= addr.Address.ToString();
        }
        catch
        {
            Row.fieldName = "WRONGADDRESS";
        }
    }

Затем вы можете использовать условное разделение, чтобы отфильтровать все недействительные записи или все, что вы хотите сделать.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.