C # код для підтвердження електронної адреси


461

Який найелегантніший код для підтвердження того, що рядок є дійсною адресою електронної пошти?



9
Подивіться на статтю Філа Хакка: " Я знав, як
перевірити

Є багато інших важливих перевірок, а не лише рядок, краще перевірити, чи існує електронна пошта на цьому smtp-сервері чи користувач вводить будь-яку електронну пошту .. тощо. або використовувати API, який буде обробляти цю інформацію, щоб ви впевнені в електронній пошті правильно, як ver-email.com
Amr Magdy


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

Відповіді:


783

Як що до цього?

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) тощо. Потім подайте попередження, що дає користувачеві шанс сказати «так, мій поштовий сервер дійсно дозволяє 🌮🍳🎁 як адресу електронної пошти».


Що стосується використання винятків для ділової логіки, я погоджуюся, що цього слід уникати. Але це один із тих випадків, коли зручність та ясність може переважати догму.

Крім того, якщо ви робите щось інше з адресою електронної пошти, це, ймовірно, потребуватиме перетворення її на адресу MailAddress. Навіть якщо ви не використовуєте цю точну функцію, ви, ймовірно, захочете використовувати той самий шаблон. Ви також можете перевірити наявність певних видів збоїв, ввівши різні винятки : нульовий, порожній або недійсний формат.


За коментарем Стюарта, це порівнює кінцеву адресу з оригінальним рядком, а не завжди повертає істину. MailAddress намагається проаналізувати рядок з пробілами на частини "Відображати ім'я" та "Адреса", тому первісна версія повертала помилкові позитиви.


--- Подальше читання ---

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

Пояснення того, що складає дійсну адресу електронної пошти


23
Насправді це невірно. a @ a - дійсна адреса електронної пошти. Дивіться haacked.com/archive/2007/08/21/… Насправді цей метод повертає неправильні результати, якщо ви використовуєте адресу з цитатами.
Cogwheel

53
+1: це найкраща відповідь, якщо ви використовуєте System.Net.Mailкласи для надсилання пошти, що ви, мабуть, є, якщо використовуєте .NET. Ми прийняли рішення використовувати цей тип перевірки просто тому, що немає сенсу приймати адреси електронної пошти - навіть дійсні - на які ми не можемо надсилати пошту.
Грег Бук

24
Я не рекомендую. Це повертається правдою:IsValidEmail("this is not valid@email$com");
Какаші

15
Мабуть, багато проблем виникає через те, що MailAddress також намагається проаналізувати DisplayName, так що "single space@domain.com" розбирає на SingleName "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: вона є в основному корпусі, але коментарі складні. Якщо ваша мета - не гнівати користувачів, то ваша перевірка не повинна бути більш обмежуючою, ніж специфікація. Єдиний спосіб по-справжньому перевірити, чи є електронний лист дійсним - це надіслати тестове повідомлення.
Cogwheel

4
Зверніть увагу, що foo.IsValid(null);повертається true.
уріг

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, якщо вказане значення є дійсним або null; в іншому випадку, 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());. Зараз я піду і знайду Реформатську церкву ще кращих версіоністів.
Марк.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 \, або ви можете надати строковий дослівний.
Nikhil Agrawal

3
Це працює, але не забувайте, RegexOptions.IgnoreCaseоскільки ця схема не дозволяє явно використовувати великі літери!
Кріс

1
Зауважте, що Regex є дуже навмисним: "Цей атрибут забезпечує перевірку електронної пошти на стороні сервера, еквівалентну валідації jquery, і тому має однаковий регулярний вираз".
Охад Шнайдер

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);
Marc

Це просто жах :)
Александру Діку

31

Особисто я хотів би сказати, що вам слід просто переконатися, що в ньому є символ @, можливо, а. характер. Існує багато регексів, які ви можете використовувати різної коректності, але я думаю, що більшість із них залишають дійсні адреси електронної пошти або пропускають недійсні. Якщо люди хочуть ввести фальшиву електронну адресу, вони поставлять підроблену. Якщо вам потрібно переконатися, що адреса електронної пошти є законною, і що особа контролює цю електронну адресу, тоді вам потрібно буде надіслати їм електронне повідомлення за допомогою спеціального кодованого посилання, щоб вони могли перевірити, чи справді це справжня адреса.


6
Я особисто думаю, що ви повинні зробити трохи більше перевірки, ніж це. Хтось зобов’язаний спробувати електронну адресу Bobby Table або ще гірше.
Люк Кінане

31
Що не так з електронною адресою таблиці бобі, якщо ви використовуєте підготовлені заяви. Ми говоримо про дійсні адреси електронної пошти, а не про інші речі, які не мають нічого спільного з тим, що становить дійсну адресу електронної пошти, як, наприклад, як правильно робити SQL запити, щоб у вас не виникли проблеми з інжекцією SQL.
Kibbee

Я думаю, ви не знаєте, що хтось туди вкладе, але зловмисник знає, що з часом цінність може надходити у вашу поштову систему. Я просто вважаю за краще піти на захист в глибину і бути трохи суворішим.
Люк Кінане

10
Це стосується поштової системи. Я б не хотіла б відкидати ідеально правильні адреси електронної пошти лише тому, що це може бути проблемою безпеки для іншої системи. Якщо всі ваші сервери електронної пошти - це неправильна адреса електронної пошти, щоб викликати проблеми із безпекою, ви, ймовірно, повинні перейти на інший сервер.
Kibbee

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

@Goner Doug, ця функціональність працюватиме так. (Bool flag = EmailAddress.IsValidEmail ())
Naveen

2
"ЦЕ" потрібно було видалити, щоб не викликати проблем із компілятором при додаванні до моєї форми.
Гонер Дуг

@Goner Doug, його функціональність працюватиме так. string email = "abc@xyz.com"; if (email.IsValidEmail ()) {return false; } else {return true;}
Naveen

14

Найелегантніший спосіб - це використання вбудованих методів .Net.

Ці методи:

  • Перевірені і перевірені. Ці методи використовуються в моїх власних професійних проектах.

  • Використовуйте внутрішні регулярні вирази, які є надійними та швидкими.

  • Зроблено Microsoft для C #. Не потрібно винаходити колесо.

  • Повернути результат булінгу. Правда означає, що електронний лист є дійсним.

Для користувачів .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 () з перевіркою на вході ==. Адреса, тому я вважаю, що це досить корисно. Не читаючи коментарів, прийнята відповідь є досить неправильною. новий MailAddress ("Foobar Some@thing.com") доводить це.
січня

@Jan FWIW, Маник бити Knickerless до EmailAddressAttributeтрохи менше чотирьох місяців, хоча це один робить зловити nullпроблему.
ruffin

7

Якщо чесно, у виробничому коді найкраще я перевіряю наявність @ символ.

Я ніколи не можу повністю перевірити електронні листи. Ви знаєте, як я бачу, чи справді це було дійсно? Якщо його надіслали. Якщо це не сталося, це погано, якщо так, життя добре. Це все, що мені потрібно знати.


6

Я вважаю, що цей регулярний вимір є гарною компромісом між перевіркою на щось більше, ніж просто знак @, і прийняттям дивних крайових випадків:

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

Це принаймні змусить вас поставити щось навколо знака @ і поставити принаймні нормальний вигляд домену.


Я придумав той самий регекс;) Це дозволяє недійсним характерам, хоча
Стефан

Ця відповідь не приймає TLD у частині домену.
Симона

@Simone, мабуть, ніхто не має електронної адреси з TLD у частині домену, хоча на практиці: serverfault.com/a/721929/167961 зауважте, що у коментарях це може бути заборонено в ці дні
Меттью Блокування

@MatthewLock Чи може це бути адреса інтрамережі? Як bob@companyinternal?
Симона

@Simone хтось у реальному житті насправді використовує цю схему?
Метью Лок

4

Перевірка електронної адреси не така проста, як може здатися. Теоретично неможливо повністю перевірити електронну адресу, використовуючи лише регулярний вираз.

Перегляньте мій пост у блозі для обговорення цього питання та F # реалізації за допомогою FParsec. [/ besless_plug]


1
Мені сподобався список альтернативних підходів; дуже цікаво.
Люк Кінане

1
Цікава стаття. Але серйозно, хто розміщує коментарі та вкладені в них електронні адреси?
Меттью Лок

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

4

Ось моя відповідь - рішення Філа не вдається для домен з однією літерою на кшталт "who@q.com". Вірите чи ні, це використовується =) (переходить, наприклад, до центурилінку).

Відповідь Філа також буде працювати лише зі стандартом PCRE ... тому C # візьме це на озброєння, але javascript буде бомбити. Це занадто складно для JavaScript. Тому ви не можете використовувати рішення Філа для атрибутів перевірки mvc.

Ось мій регекс. Це буде добре працювати з атрибутами перевірки MVC.
- Все до @ спрощується, так що принаймні javascript буде працювати. Я добре розслаблюючу перевірку тут, доки сервер Exchange не дасть мені 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 помилкою виконання, як тільки ви спробуєте надіслати повідомлення.


що, здається, найкраща наймисливіша / розумна / реальна відповідь, дякую Ральфе!
Fattie

це найкраща відповідь поки! Я не можу повірити, що неправильне рішення, яке сприймає basket@ballяк дійсну адресу електронної пошти, отримало правильну відповідь, як і всі ці результати. Все одно, дякую!
disasterkid

Дякую, це найкраще рішення і на нього слід прийняти відповідь.
Bat_Programmer

3

Якщо ви насправді, а я маю на увазі, дійсно хочете дізнатися, чи адреса електронної пошти дійсна ... попросіть обмінник пошти довести це, не потрібен регулярний вираз. Я можу надати код за запитом.

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

Це, як ви можете собі уявити, дуже дорогий час і мудрий, але покладається на smtp, але це працює.


Ви створювали підробки, заглушки та / або макети для цих інтерфейсів?
Марк A

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 for .NET нарешті намагається кілька разів запитувати цільовий обмінник пошти за різними сфабрикованими адресами ".
Matthew Lock

Дякую, @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 має своє власне визначення дійсного. пов'язана дискусія
waitforit

2

Тут є багато вагомих відповідей. Однак я рекомендую зробити крок назад. @Cogwheel відповідає на питання https://stackoverflow.com/a/1374644/388267 . Тим не менш, сценарій масової перевірки може бути дорогим, якщо багато перевірених адрес електронної пошти недійсні. Я пропоную використати трохи логіки, перш ніж увійти в його блок-проб. Я знаю, що наступний код може бути написаний за допомогою 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

/ Використання внутрішнього Regex, який використовується при створенні "нового 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ö", і він кидає помилку на mandril api
MonsterMMORPG

1
По-перше, електронний лист є дійсним wrt example@example.co або example@example.com .... У електронній пошті є всі дійсні рядки та критерії, за винятком останнього символу "ö", і ви можете легко додати просту умову для перевірки такого символу . По-друге, я не впевнений у тій помилці api mandrill, ви, можливо, захочете перевірити ваш спосіб використання bcos. Я використовував цю перевірку на інших середовищах / api, і це було добре для мене.
Aina Ademola 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

Простий спосіб ідентифікації електронного листа є дійсним чи ні.

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

Я в кінцевому підсумку скористався цим регулярним виразом, оскільки він успішно перевіряє коми, коментарі, символи Unicode та адреси домену 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.