Kode C # untuk memvalidasi alamat email

461

Apa kode paling elegan untuk memvalidasi bahwa string adalah alamat email yang valid?

leora
sumber
9
Silakan lihat artikel Phil Haack: " Saya Tahu Cara Memvalidasi Alamat Email Sampai Saya Baca RFC "
Luke Quinane
ada banyak validasi penting lainnya tidak hanya string, lebih baik untuk memeriksa apakah email ada di server smtp ini atau pengguna memasukkan email apa pun .. dll atau menggunakan API yang akan menangani itu untuk Anda untuk memastikan email benar seperti ver-email.com
Amr Magdy
Lnk
Kishore Sahasranaman
Anda bisa menggunakan pustaka github.com/jstedfast/EmailValidation .
Mohammad Reza Sadreddini

Jawaban:

784

Bagaimana dengan ini?

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

Untuk memperjelas, pertanyaannya adalah menanyakan apakah string tertentu merupakan representasi yang valid dari alamat email, bukan apakah alamat email adalah tujuan yang valid untuk mengirim pesan. Untuk itu, satu-satunya cara nyata adalah mengirim pesan untuk mengonfirmasi.

Perhatikan bahwa alamat email lebih mudah memaafkan daripada yang mungkin Anda bayangkan sebelumnya. Ini semua adalah formulir yang benar-benar valid:

  • cog @ wheel
  • "roda gigi jeruk" @ example.com
  • 123@$.xyz

Untuk sebagian besar kasus penggunaan, "palsu" palsu jauh lebih buruk bagi pengguna Anda dan pembuktian di masa depan daripada "valid" palsu. Inilah artikel yang dulunya adalah jawaban yang diterima untuk pertanyaan ini (jawaban itu telah dihapus). Ini memiliki lebih banyak detail dan beberapa ide lain tentang cara mengatasi masalah.

Memberikan pemeriksaan kewarasan masih merupakan ide bagus untuk pengalaman pengguna. Anggap alamat email itu valid, Anda bisa mencari domain tingkat atas yang diketahui, memeriksa domain untuk data MX, memeriksa kesalahan pengejaan dari nama domain umum (gmail.cmo), dll. Lalu berikan peringatan yang memberi pengguna kesempatan untuk mengatakan "ya, server email saya benar-benar mengizinkan 🌮🍳🎁 sebagai alamat email."


Adapun untuk menggunakan penanganan pengecualian untuk logika bisnis, saya setuju bahwa itu adalah hal yang harus dihindari. Tetapi ini adalah salah satu kasus di mana kenyamanan dan kejelasan mungkin melebihi dogma.

Selain itu, jika Anda melakukan hal lain dengan alamat email, itu mungkin akan melibatkan mengubahnya menjadi MailAddress. Bahkan jika Anda tidak menggunakan fungsi persis ini, Anda mungkin ingin menggunakan pola yang sama. Anda juga dapat memeriksa jenis kegagalan tertentu dengan menangkap pengecualian berbeda : format null, kosong, atau tidak valid.


Per komentar Stuart, ini membandingkan alamat akhir dengan string asli alih-alih selalu kembali benar. MailAddress mencoba mengurai string dengan spasi ke bagian "Nama Tampilan" dan "Alamat", sehingga versi asli mengembalikan positif palsu.


--- Bacaan lebih lanjut ---

Dokumentasi untuk System.Net.Mail.MailAddress

Penjelasan tentang apa yang membuat alamat email yang valid

Roda gigi
sumber
23
Sebenarnya itu tidak salah. a @ a adalah alamat email yang valid. Lihat haacked.com/archive/2007/08/21/... Bahkan, metode ini mengembalikan hasil yang salah jika Anda menggunakan alamat dengan tanda kutip.
Cogwheel
53
+1: Ini adalah jawaban terbaik jika Anda menggunakan System.Net.Mailkelas - kelas untuk mengirim email, yang mungkin Anda lakukan jika Anda menggunakan .NET. Kami membuat keputusan untuk menggunakan jenis validasi ini hanya karena tidak ada gunanya kami menerima alamat email - bahkan yang valid - yang tidak dapat kami kirimi surat.
Greg Beech
24
Saya tidak merekomendasikan. Ini mengembalikan true:IsValidEmail("this is not valid@email$com");
Kakashi
15
Banyak masalah tampaknya karena MailAddress mencoba mem-parsing DisplayName juga, jadi "single [email protected]" mem-parsing ke DisplayName "single" dan Address "[email protected]". Perbaikan untuk ini adalah untuk: kembali (addr.Address == email);
Stuart
18
Saya suka ini; Saya tidak mendapatkan paksaan untuk menjadi lebih ketat daripada spesifikasi yang sebenarnya. Negatif palsu jauh lebih buruk daripada positif palsu ("Apa maksudmu email saya tidak valid? ")
Casey
242

Ini adalah pertanyaan lama, tetapi semua jawaban yang saya temukan di SO, termasuk yang lebih baru, dijawab sama dengan yang ini. Namun, di .Net 4.5 / MVC 4 Anda dapat menambahkan validasi alamat email ke formulir dengan menambahkan anotasi [EmailAddress] dari System.ComponentModel.DataAnnotations, jadi saya bertanya-tanya mengapa saya tidak bisa hanya menggunakan fungsi bawaan dari. Bersih secara umum.

Ini sepertinya berhasil, dan menurut saya cukup elegan:

using System.ComponentModel.DataAnnotations;

class ValidateSomeEmails
{
    static void Main(string[] args)
    {
        var foo = new EmailAddressAttribute();
        bool bar;
        bar = foo.IsValid("[email protected]");         //true
        bar = foo.IsValid("[email protected]");       //true
        bar = foo.IsValid("[email protected]");     //true
        bar = foo.IsValid("[email protected]");      //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("[email protected]"))
            bar = true;    
    }
}
imjosh
sumber
4
Keren, walaupun mengecewakan bahwa MS tidak dapat membuat ini setuju dengan dokumentasi mereka sendiri . Ini menolak [email protected]
Casey
13
Perhatikan bahwa EmailAddressAttributekurang permisif daripada System.Net.Mail.MailAddress- misalnya, MailAddressmenerima alamat untuk TLD. Hanya sesuatu yang perlu diingat jika Anda harus seizin mungkin.
Aaroninus
5
@ Cogwheel: jika jawabannya ada di suatu tempat di komentar itu mungkin harus ditambahkan ke bagian utama dari jawabannya.
hofnarwillie
6
@hofnarwillie: ada di badan utama, tapi komentarnya rumit. Jika tujuan Anda adalah untuk tidak membuat marah pengguna Anda, maka validasi Anda seharusnya tidak lebih ketat dari spesifikasi. Satu-satunya cara untuk memverifikasi apakah email benar atau tidak adalah dengan mengirim pesan pengujian.
Cogwheel
4
Harap dicatat bahwa foo.IsValid(null);kembali true.
urig
62

Saya menggunakan metode single liner ini yang berfungsi untuk saya

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

Per komentar, ini akan "gagal" jika source(alamat email) adalah nol.

public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);
Manik Arora
sumber
1
Ini tidak berhasil untuk saya; Saya mendapatkan, "'Anotasi Data' tidak ada ... apakah Anda melewatkan referensi perakitan?" Referensi mana yang harus saya tambahkan?
B. Clay Shannon
Ini akan mengembalikan true jika sumbernya nol. Lihat msdn.microsoft.com/en-us/library/hh192424 "benar jika nilai yang ditentukan valid atau null; jika tidak, false."
jao
2
Versi yang lebih baik:public static Boolean IsValidMailAddress(this String pThis) => pThis == null ? false : new EmailAddressAttribute().IsValid(pThis);
Sebastian Hofmann
7
Atau bahkan lebih baik:public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);
Patrik Melander
1
Saya tidak berpikir metode ekstensi ini harus kembali secara diam-diam falseuntuk string nol. Itu sebabnya saya mengusulkan (bahkan lebih baik lebih baik) ++ versi: public static bool IsValidEmailAddress(this string address) => new EmailAddressAttribute().IsValid(address ?? throw new ArgumentNullException());. Sekarang saya akan pergi dan menemukan Gereja Reformed dari Bahkan Lebih Baik Versiis.
Marc.2377
41

.net 4.5 menambahkan System.ComponentModel.DataAnnotations.EmailAddressAttribute

Anda dapat menelusuri sumber EmailAddressAttribute , ini adalah Regex yang digunakan secara internal:

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])))\.?$";
Chad Grant
sumber
2
Sayangnya, EmaillAddressAttribute memungkinkan Ñ yang bukan karakter yang valid untuk email
BZ
16
@ BZ Ya itu. Menurut Anda mengapa tidak?
Casey
@Chad Grant: Ini adalah versi C #. Bisakah Anda memberikan yang VB.Net. Karena itu akan keluar dari karakter seperti \\ to \ atau Anda dapat memberikan string kata demi kata.
Nikhil Agrawal
3
Ini berfungsi, tetapi jangan lupa RegexOptions.IgnoreCasekarena pola ini tidak mengizinkan huruf kapital secara eksplisit!
Chris
1
Perhatikan bahwa Regex sangat disengaja: "Atribut ini memberikan validasi email sisi-server yang setara dengan validasi jquery, dan karenanya berbagi ekspresi reguler yang sama".
Ohad Schneider
38

Saya mengambil jawaban Phil dari # 1 dan menciptakan kelas ini. Sebut saja seperti ini:bool isValid = Validator.EmailIsValid(emailString);

Ini kelasnya:

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;
    }
}
David Silva Smith
sumber
5
Hanya yang kecil, tapi saya akan menggunakan: return (! String.IsNullOrEmpty (emailAddress)) && ValidEmailRegex.IsMatch (emailAddress);
Marc
Ini hanya horor :)
Alexandru Dicu
31

Secara pribadi, saya akan mengatakan bahwa Anda harus memastikan ada simbol @ di sana, dengan kemungkinan a. karakter. Ada banyak regex yang dapat Anda gunakan dengan kebenaran yang berbeda-beda, tetapi saya rasa sebagian besar dari ini mengabaikan alamat email yang valid, atau membiarkan yang tidak valid melaluinya. Jika orang ingin memasukkan alamat email palsu, mereka akan memasukkan alamat palsu. Jika Anda perlu memverifikasi bahwa alamat email itu sah, dan bahwa orang itu mengendalikan alamat email itu, maka Anda harus mengirimi mereka email dengan tautan kode khusus sehingga mereka dapat memverifikasi bahwa alamat itu memang alamat asli.

Kibbee
sumber
6
Saya pribadi berpikir Anda harus melakukan validasi sedikit lebih dari itu. Seseorang pasti akan mencoba alamat email Bobby Table atau yang lebih buruk.
Luke Quinane
31
Apa yang salah dengan alamat email bobby table jika Anda menggunakan pernyataan yang disiapkan. Kita berbicara tentang alamat email yang valid, bukan hal lain yang tidak ada hubungannya dengan apa yang membentuk alamat email yang valid, seperti cara melakukan query SQL dengan benar sehingga Anda tidak mendapatkan masalah injeksi SQL.
Kibbee
Saya kira Anda tidak tahu apa yang akan dimasukkan seseorang ke sana tetapi orang jahat tahu bahwa nilainya mungkin pada akhirnya dimasukkan ke dalam sistem email Anda. Saya hanya lebih memilih untuk pergi pertahanan secara mendalam dan menjadi sedikit lebih ketat.
Luke Quinane
10
Itu yang perlu dikhawatirkan sistem email. Saya tidak akan seenaknya menolak alamat email yang benar-benar valid hanya karena itu bisa menjadi masalah keamanan dengan beberapa sistem lain. Jika semua yang dibutuhkan oleh server email Anda adalah alamat email yang salah untuk menyebabkan masalah keamanan, Anda mungkin harus beralih ke server lain.
Kibbee
4
Pertahanan mendalam hanya berfungsi jika setiap tingkat bawang keamanan Anda tidak busuk. Satu lapisan busuk berarti Anda merusak seluruh bawang. Menolak "[email protected]" karena Anda ingin mempertahankan diri dari kerentanan dalam penyandian μ-law Sun tidak masuk akal, bukan? Jangan tertawa, itu terjadi pada saya. Alasan saya berkomentar di sini adalah karena Medicare Australia tidak mengizinkan alamat ".au", hanya ".com". Baca juga Mark Swanson, "Bagaimana tidak memvalidasi email,", mdswanson.com/blog/2013/10/14/…
ManicDee
17

Saya pikir cara terbaik adalah sebagai berikut:

    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;
    }

Anda dapat memiliki fungsi statis ini di kelas umum.

Poyson1
sumber
Jawaban ini tidak menerima alamat dengan TLD di bagian domain.
Simone
15

Kode pendek dan akurat

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);
}
Naveen
sumber
2
Terima kasih atas solusinya
Jack Gajanan
Saya harus mengubah bool statis publik IsValidEmail (email string ini) menjadi bool publik statis IsValidEmail (email string) untuk menghindari INI: stackoverflow.com/questions/10412233/…
Goner Doug
@Goner Doug, functionlity ini akan berfungsi seperti ini. (Bool flag = EmailAddress.IsValidEmail ())
Naveen
2
"INI" perlu dihapus untuk menghindari masalah penyusun saat ditambahkan ke formulir saya.
Goner Doug
@Goner Doug, Functionlity-nya akan bekerja seperti ini. string email = "[email protected]"; if (email.IsValidEmail ()) {return false; } else {return true;}
Naveen
14

Cara paling elegan adalah menggunakan metode .Net.

Metode-metode ini:

  • Sudah dicoba dan diuji. Metode ini digunakan dalam proyek profesional saya sendiri.

  • Gunakan ekspresi reguler secara internal, yang dapat diandalkan dan cepat.

  • Dibuat oleh Microsoft untuk C #. Tidak perlu menemukan kembali roda.

  • Kembalikan hasil bool. Benar artinya email itu valid.

Untuk pengguna .Net 4.5 dan lebih tinggi

Tambahkan Referensi ini ke proyek Anda:

System.ComponentModel.DataAnnotations

Sekarang Anda dapat menggunakan kode berikut:

(new EmailAddressAttribute().IsValid("[email protected]"));

Contoh penggunaan

Berikut adalah beberapa metode untuk menyatakan:

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;

}

... dan kode menunjukkan mereka dalam aksi:

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

}

Selain itu, contoh ini:

  • Meluas melampaui spesifikasi karena string tunggal digunakan untuk berisi 0, satu atau banyak alamat email yang diseratkan oleh titik koma ;.
  • Jelas menunjukkan cara menggunakan metode IsValid objek EmailAddressAttribute.

Alternatif, untuk pengguna versi .Net kurang dari 4,5

Untuk situasi di mana .Net 4.5 tidak tersedia, saya menggunakan solusi berikut:

Secara khusus, saya menggunakan:

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;

}
WonderWorker
sumber
1
@ThomasAyoub Saya belum melihat jawaban EmailAddressAttribute, dan tidak ada jawaban yang menggunakan MailAddress baru () dengan cek pada input == .Address jadi saya pikir ini cukup berguna. Tanpa membaca komentar, jawaban yang diterima cukup salah. MailAddress baru ("Foobar [email protected]") membuktikan hal itu.
Jan
@ Jan fwiw, Manik mengalahkan Knickerless hingga EmailAddressAttributehampir empat bulan, meskipun yang satu ini benar-benar menangkap nullmasalah.
ruffin
7

Sejujurnya, dalam kode produksi, yang terbaik yang saya lakukan adalah memeriksa @simbol.

Saya tidak pernah di tempat untuk sepenuhnya memvalidasi email. Anda tahu bagaimana saya melihat apakah itu benar-benar valid? Jika itu dikirim. Jika tidak, itu buruk, jika itu terjadi, hidup itu baik. Itu saja yang perlu saya ketahui.

Sutra Siang
sumber
6

Saya menemukan regex ini sebagai trade off yang baik antara memeriksa sesuatu lebih dari sekedar tanda @, dan menerima kasus tepi aneh:

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

Setidaknya itu akan membuat Anda menaruh sesuatu di sekitar tanda @, dan menempatkan setidaknya domain yang terlihat normal.

Matthew Lock
sumber
Saya datang dengan regex yang sama;) Itu memang memungkinkan charachters yang tidak valid
Stefan
Jawaban ini tidak menerima TLD di bagian domain.
Simone
@Simone mungkin tidak ada yang memiliki alamat email dengan TLD di bagian domain meskipun dalam praktiknya: serverfault.com/a/721929/167961 catatan dalam komentar itu mungkin dilarang hari ini
Matthew Lock
@ MatthewLock Mungkinkah itu alamat intranet? Suka bob@companyinternal?
Simone
@Simone apakah ada orang di dunia nyata yang menggunakan skema itu?
Matthew Lock
4

Validasi alamat email tidak semudah kelihatannya. Sebenarnya secara teori tidak mungkin untuk memvalidasi alamat email sepenuhnya hanya dengan menggunakan ekspresi reguler.

Lihat posting blog saya tentang hal ini untuk diskusi tentang subjek dan implementasi F # menggunakan FParsec. [/ shameless_plug]

Mauricio Scheffer
sumber
1
Saya menyukai Anda daftar pendekatan alternatif; sangat menarik.
Luke Quinane
1
Artikel menarik. Tapi serius siapa yang memberikan komentar, dan yang bersarang di sana, di alamat email?
Matthew Lock
3
@ ahthew Saya tidak tahu mengapa IETF bahkan mengizinkannya, tapi itu mungkin , jadi validasi yang menyeluruh harus memperhitungkannya.
Mauricio Scheffer
4

Inilah jawaban saya - Solusi Phil gagal untuk domain satu huruf seperti "[email protected]". Percaya atau tidak, itu digunakan =) (pergi ke tautan abad, misalnya).

Jawaban Phil juga akan bekerja hanya dengan standar PCRE ... jadi C # akan menerimanya, tetapi javascript akan mengebom. Terlalu rumit untuk javascript. Jadi, Anda tidak dapat menggunakan solusi Phil untuk atribut validasi MVC.

Ini regex saya. Ini akan bekerja dengan baik dengan atribut validasi MVC.
- Segala sesuatu sebelum @ disederhanakan, sehingga setidaknya javascript akan berfungsi. Saya validasi santai di sini selama server exchange tidak memberi saya 5.1.3. - Semuanya setelah @ adalah solusi Phil yang dimodifikasi untuk domain huruf tunggal.

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]$";

Bagi orang yang menyarankan menggunakan system.net.mail MailMessage (), hal itu adalah CARA untuk fleksibel. Tentu, C # akan menerima email, tetapi kemudian server pertukaran akan mengebom dengan kesalahan runtime 5.1.3 segera setelah Anda mencoba mengirim email.

Ralph N
sumber
yang tampaknya menjadi jawaban dunia nyata paling bijaksana / masuk akal / terbaik, terima kasih Ralph!
Fattie
ini adalah jawaban terbaik sejauh ini! Saya tidak percaya solusi buruk yang diterima basket@ballsebagai alamat email yang valid telah mendapatkan jawaban yang benar serta semua upvotes itu. Bagaimanapun, terima kasih!
disasterkid
Terima kasih ini adalah solusi terbaik dan harus diterima jawabannya.
Bat_Programmer
3

Jika Anda benar-benar dan maksud saya benar-benar ingin tahu apakah alamat email itu valid ... minta penukar email untuk membuktikannya, tidak perlu regex. Saya dapat memberikan kode jika diminta.

Langkah-langkah umum adalah sebagai berikut: 1. apakah alamat email memiliki bagian nama domain? (indeks @> 0) 2. menggunakan kueri DNS, tanyakan apakah domain memiliki penukar mail 3. buka koneksi tcp ke mail exchanger 4. menggunakan protokol smtp, buka pesan ke server menggunakan alamat email sebagai penerima 5. parsing respons server. 6. keluar dari pesan jika Anda sampai sejauh ini, semuanya baik-baik saja.

Ini seperti yang dapat Anda bayangkan, waktu yang sangat mahal dan bergantung pada smtp, tetapi berhasil.

Joe Caffeine
sumber
Apakah Anda membuat palsu, bertopik dan / atau mengolok-olok untuk antarmuka itu?
Mark A
1
Itu tidak akan berhasil. Protokol smtp untuk memverifikasi alamat email telah LAMA sudah tidak digunakan / tidak digunakan. Ini dianggap praktik buruk untuk mengaktifkannya di server email karena spammer menggunakan fungsionalitas itu.
Chad Grant
Saya akan menyimpan saran Anda hingga poin 2. Jauh lebih tahan-bukti daripada memeriksa pola nama domain yang dikenal.
Simone
Nitpicking, tetapi tentukan "memiliki penukar email" ? Jika tidak ada catatan MX, SMTP harus kembali ke catatan A / AAAA, sesuai RFC2821 / 5321. Jika catatan MX memang ada, itu masih mungkin tidak menunjukkan penukar email ada (RFC7505). Sungguh, satu-satunya cara adalah mengirimi mereka surat dengan tautan ajakan bertindak, dan menunggu mereka membalas ...
jimbobmcgee
2

Secara umum, ekspresi reguler untuk memvalidasi alamat email bukanlah hal yang mudah untuk dibuat; pada saat penulisan ini, sintaksis alamat email harus mengikuti standar yang relatif tinggi dan menerapkan semuanya dalam ekspresi reguler secara praktis tidak mungkin!

Saya sangat menyarankan Anda untuk mencoba EmailVerify.NET kami , perpustakaan .NET dewasa yang dapat memvalidasi alamat email mengikuti semua standar IETF saat ini (RFC 1123, RFC 2821, RFC 2822, RFC 3696, RFC 4291, RFC 5321 dan RFC 5322) , menguji catatan DNS terkait, memeriksa apakah kotak surat target dapat menerima pesan dan bahkan dapat mengetahui apakah alamat yang diberikan dapat dibuang atau tidak.

Penafian: Saya adalah pengembang utama untuk komponen ini.

Efran Cobisi
sumber
Impresif! "Selanjutnya, ia mencoba untuk menghubungi penukar email yang bertanggung jawab atas alamat email yang diberikan dan memulai dialog SMTP palsu dengan server itu, meniru server email nyata. Dengan cara ini memastikan bahwa server dapat menangani email untuk alamat tersebut. Banyak server SMTP sebenarnya memberikan jawaban positif palsu sebagai perlindungan terhadap spammer: untuk mengatasi masalah ini, EmailVerify untuk .NET akhirnya berupaya untuk meminta penukar email target beberapa kali dengan alamat palsu yang berbeda. "
Matthew Lock
Terima kasih, @MatthewLock;)
Efran Cobisi
Bagus, tapi saya hanya melihat edisi berbayar. Adakah rencana untuk edisi komunitas / OpenSource?
Ohad Schneider
1
@OhadSchneider Ya: kami menawarkan versi gratis dari teknologi validasi email kami melalui Verifalia, layanan verifikasi email SaaS kami . Verifalia hadir dengan SDK sumber terbuka dan gratis untuk platform pengembangan perangkat lunak utama, termasuk .NET .
Efran Cobisi
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;
        }
pengguna2211290
sumber
Ini akan gagal memvalidasi [email protected] sebagai alamat email yang valid.
Ray Cheng
2

Jika Anda menggunakan FluentValidation, Anda dapat menulis sesuatu yang sederhana seperti ini:

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;
Ulysses Alves
sumber
2

sedikit modifikasi untuk jawaban @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;
  }
}
menunggu untuk itu
sumber
Ini sepertinya tidak membantu ... Console.WriteLine(MailAddress("asdf@asdf.").Address);menghasilkan "asdf @ asdf.", Yang tidak valid.
Langdon
Net tampaknya memiliki definisi sendiri yang valid. diskusi
waitforit
2

Ada banyak jawaban kuat di sini. Namun, saya menyarankan agar kita mengambil langkah mundur. @Cogwheel menjawab pertanyaan https://stackoverflow.com/a/1374644/388267 . Namun demikian, ini bisa mahal dalam skenario validasi massal, jika banyak alamat email yang divalidasi tidak valid. Saya menyarankan agar kita menggunakan sedikit logika sebelum kita masuk ke blok try-catch-nya. Saya tahu bahwa kode berikut dapat ditulis menggunakan RegEx tetapi itu bisa mahal bagi pengembang baru untuk mengerti. Ini adalah nilai twopence saya:

    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;
        }
    }
CarneyCode
sumber
2

Jawaban yang paling banyak dipilih dari @Cogwheel adalah jawaban terbaik namun saya telah mencoba menerapkan trim()metode string sehingga akan memangkas semua ruang putih pengguna dari string mulai dari awal hingga akhir. Periksa kode di bawah untuk contoh lengkap-

bool IsValidEmail(string email)
{
    try
    {
        email = email.Trim();
        var addr = new System.Net.Mail.MailAddress(email);
        return addr.Address == email;
    }
    catch
    {
        return false;
    }
}
Liakat
sumber
Risiko dari hal ini adalah Anda memvalidasi alamat e-mail yang berbeda dari sumbernya, membuat Anda berpikir bahwa Anda dapat mengirim email ke (dalam hal ini) versi tidak terpotong dari alamat e-mail yang ditentukan. Pendekatan yang lebih baik adalah membuat metode terpisah SanitizeEmail(string email), menggunakan hasil dari metode itu untuk memvalidasi dan mengirim email ke.
Marco de Zeeuw
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);
}
ErwanLent
sumber
1

Periksa string email adalah format yang benar atau format yang salah oleh 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";
        }
    }
rktuxyn
sumber
1

/ Menggunakan Internal Regex yang digunakan dalam membuat "EmailAddressAttribute ();" baru komponen dalam .Net4.5 >>> menggunakan System.ComponentModel.DataAnnotations; // Untuk Memvalidasi Alamat Email ...... Diuji dan Bekerja.

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;
    }
}

Anda juga dapat menggunakan ini:

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

Aina Ademola C
sumber
dikatakan benar untuk email ini: "[email protected]ö" dan itu melempar kesalahan pada mandrill api
MonsterMMORPG
1
Pertama, email tersebut benar wrt [email protected] atau [email protected] .... Email memiliki semua string dan kriteria yang valid kecuali untuk karakter terakhir "ö" dan Anda dapat dengan mudah menambahkan kondisi sederhana untuk memvalidasi karakter tersebut . Kedua, saya tidak yakin tentang kesalahan api mandrill itu, Anda mungkin ingin memverifikasi metode penggunaan bcos. Saya telah menggunakan validasi ini pada beberapa lingkungan lain / api dan sudah baik bagi saya.
Aina Ademola C
1

Saya ringkas jawaban Poyson 1 seperti:

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);
}
B. Clay Shannon
sumber
1

Cara sederhana untuk mengidentifikasi emailid itu valid atau tidak.

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})(\]?)$");
}
Amit Gorvadiya
sumber
1

Ada masalah budaya dalam regex di C # daripada js. Jadi kita perlu menggunakan regex dalam mode AS untuk memeriksa email. Jika Anda tidak menggunakan mode ECMAScript, karakter khusus bahasa Anda tersirat dalam AZ dengan regex.

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)
mkysoft
sumber
1

Saya akhirnya menggunakan regex ini, karena berhasil memvalidasi koma, komentar, karakter Unicode, dan alamat domain IP (v4).

Alamat yang valid adalah:

"" @ example.org

(comment)[email protected]

тест@example.org

ტესტი @ example.org

test @ [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,}))$";
dpopov
sumber
1

Yang sederhana tanpa menggunakan Regex (yang saya tidak suka karena keterbacaannya yang buruk):

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;
}

Contoh:

Ini dimaksudkan untuk menjadi sederhana dan karena itu tidak berurusan dengan kasus-kasus langka seperti email dengan domain yang diberi tanda kurung yang berisi spasi (biasanya diizinkan), email dengan alamat IPv6, dll.

Merek
sumber
1

Ini jawaban untuk pertanyaan Anda.

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;

   }

}
Parsa Karami
sumber
1

Berdasarkan jawaban dari @Cogwheel saya ingin membagikan solusi yang dimodifikasi yang berfungsi untuk SSIS dan "Script Component":

  1. Tempatkan "Script Component" ke dalam Arus Data Anda terhubung dan kemudian buka.
  2. Di bagian "Kolom Input" setel bidang yang berisi Alamat Email ke "ReadWrite" (dalam contoh 'fieldName').
  3. Beralih kembali ke bagian "Script" dan klik "Edit Script". Maka Anda harus menunggu setelah kode terbuka.
  4. Tempatkan kode ini di metode yang benar:

    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";
        }
    }

Kemudian Anda dapat menggunakan Split Bersyarat untuk memfilter semua catatan yang tidak valid atau apa pun yang ingin Anda lakukan.

pengguna3772108
sumber