Mã C # để xác thực địa chỉ email


461

Mã thanh lịch nhất để xác nhận rằng một chuỗi là một địa chỉ email hợp lệ là gì?




Có nhiều xác nhận quan trọng khác không chỉ là chuỗi, tốt hơn là kiểm tra xem email có tồn tại ở máy chủ smtp này hay người dùng đang nhập bất kỳ email nào, v.v. hoặc sử dụng API sẽ xử lý để bạn chắc chắn rằng email là chính xác như ver-email.com
Amr Magdy


bạn có thể sử dụng thư viện github.com/jstedfast/EmailValidation .
Mohammad Reza Sadreddini

Câu trả lời:


784

Cái này thì sao?

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

Để làm rõ, câu hỏi đặt ra là liệu một chuỗi cụ thể có phải là đại diện hợp lệ của địa chỉ email không, liệu địa chỉ email có phải là đích đến hợp lệ để gửi thư hay không. Đối với điều đó, cách thực sự duy nhất là gửi tin nhắn để xác nhận.

Lưu ý rằng địa chỉ e-mail dễ tha thứ hơn bạn nghĩ trước tiên. Đây là tất cả các hình thức hoàn toàn hợp lệ:

  • bánh răng @
  • "Bánh răng cam" @ example.com
  • 123@$.xyz

Đối với hầu hết các trường hợp sử dụng, "không hợp lệ" sai sẽ tệ hơn nhiều đối với người dùng của bạn và bằng chứng trong tương lai so với "sai" hợp lệ. Đây là một bài viết từng là câu trả lời được chấp nhận cho câu hỏi này (câu trả lời đó đã bị xóa). Nó có nhiều chi tiết hơn và một số ý tưởng khác về cách giải quyết vấn đề.

Cung cấp kiểm tra vệ sinh vẫn là một ý tưởng tốt cho trải nghiệm người dùng. Giả sử địa chỉ e-mail là hợp lệ, bạn có thể tìm các tên miền cấp cao nhất đã biết, kiểm tra tên miền cho bản ghi MX, kiểm tra lỗi chính tả từ các tên miền phổ biến (gmail.cmo), v.v. Sau đó đưa ra cảnh báo cho người dùng một cơ hội để nói "có, máy chủ thư của tôi thực sự cho phép làm địa chỉ email."


Đối với việc sử dụng xử lý ngoại lệ cho logic kinh doanh, tôi đồng ý rằng đó là một điều cần tránh. Nhưng đây là một trong những trường hợp mà sự thuận tiện và rõ ràng có thể vượt xa giáo điều.

Ngoài ra, nếu bạn làm bất cứ điều gì khác với địa chỉ e-mail, có thể sẽ liên quan đến việc chuyển nó thành MailAddress. Ngay cả khi bạn không sử dụng chức năng chính xác này, bạn có thể sẽ muốn sử dụng cùng một mẫu. Bạn cũng có thể kiểm tra các loại lỗi cụ thể bằng cách bắt các ngoại lệ khác nhau : định dạng rỗng, rỗng hoặc không hợp lệ.


Theo nhận xét của Stuart, điều này so sánh địa chỉ cuối cùng với chuỗi gốc thay vì luôn trả về đúng. MailAddress cố phân tích một chuỗi có khoảng trắng thành các phần "Tên hiển thị" và "Địa chỉ", do đó phiên bản gốc đã trả về dương tính giả.


--- Đọc thêm ---

Tài liệu cho System.Net.Mail.MailAddress

Giải thích về những gì tạo nên một địa chỉ email hợp lệ


23
Trên thực tế, điều đó không chính xác. a @ a là một địa chỉ email hợp lệ. Xem haacked.com/archive 2007/08/21 / Trên thực tế, phương pháp này không trả về kết quả không chính xác nếu bạn sử dụng một địa chỉ có dấu ngoặc kép.
Bánh răng

53
+1: Đây là câu trả lời tốt nhất nếu bạn đang sử dụng các System.Net.Maillớp để gửi thư, mà bạn có thể là nếu bạn đang sử dụng .NET. Chúng tôi đã đưa ra quyết định sử dụng loại xác nhận này đơn giản vì chúng tôi không chấp nhận địa chỉ email - ngay cả những địa chỉ hợp lệ - mà chúng tôi không thể gửi thư đến.
Greg Beech

24
Tôi không khuyên bạn nên. Nó trả về đúng:IsValidEmail("this is not valid@email$com");
Kakashi

15
Rất nhiều vấn đề dường như là do MailAddress cũng cố phân tích DisplayName, do đó, "single space@domain.com" phân tích thành DisplayName "single" và Địa chỉ "space@domain.com". Một sửa chữa cho điều này là: return (addr.Address == email);
Stuart

18
Tôi thích điều này; Tôi không bắt buộc phải hạn chế hơn thông số kỹ thuật thực tế. Phủ định sai là tồi tệ hơn nhiều so với dương tính giả ("ý bạn là gì e-mail của tôi không hợp lệ? ")
Casey

242

Đây là một câu hỏi cũ, nhưng tất cả các câu trả lời tôi đã tìm thấy trên SO, bao gồm cả những câu hỏi gần đây hơn, đều được trả lời tương tự như câu hỏi này. Tuy nhiên, trong .Net 4.5 / MVC 4, bạn có thể thêm xác thực địa chỉ email vào một biểu mẫu bằng cách thêm chú thích [EmailAddress] từ System.ComponentModel.DataAnnotations, vì vậy tôi đã tự hỏi tại sao tôi không thể sử dụng chức năng tích hợp từ đó. Net nói chung.

Điều này có vẻ hiệu quả và đối với tôi khá thanh lịch:

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
Thật tuyệt, mặc dù thật đáng thất vọng khi MS không thể đồng ý với tài liệu của họ . Điều này từ chối js@proseware.com9
Casey

13
Lưu ý rằng EmailAddressAttributeít được phép hơn System.Net.Mail.MailAddress- ví dụ, MailAddresschấp nhận một địa chỉ cho TLD. Chỉ cần một cái gì đó để ghi nhớ nếu bạn cần phải được cho phép càng tốt.
Aaroninus

5
@Cogwheel: nếu câu trả lời nằm ở đâu đó trong các bình luận thì có lẽ nên thêm vào phần chính của câu trả lời.
hofnarwillie

6
@hofnarwillie: đó là trong cơ thể chính, nhưng các ý kiến ​​công phu. Nếu mục tiêu của bạn là không chọc giận người dùng thì việc xác nhận của bạn không nên hạn chế hơn thông số kỹ thuật. Cách duy nhất để thực sự xác minh xem e-mail có hợp lệ hay không là gửi tin nhắn kiểm tra.
Bánh răng

4
Xin lưu ý rằng foo.IsValid(null);trả lại true.
urig

62

Tôi sử dụng phương pháp lót đơn này có tác dụng với tôi-

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

Theo các bình luận, điều này sẽ "thất bại" nếu source(địa chỉ email) là null.

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

1
Điều này không làm việc cho tôi; Tôi nhận được, "'Chú thích dữ liệu' không tồn tại ... bạn có đang thiếu tham chiếu lắp ráp không?" Tôi cần thêm tài liệu tham khảo nào?
B. Clay Shannon

Điều này sẽ trả về true nếu nguồn là null. Xem msdn.microsoft.com/en-us/l Library / hh192424 "đúng nếu giá trị được chỉ định là hợp lệ hoặc null; nếu không, sai."
jao

2
Một phiên bản tốt hơn:public static Boolean IsValidMailAddress(this String pThis) => pThis == null ? false : new EmailAddressAttribute().IsValid(pThis);
Sebastian Hofmann

7
Hoặc thậm chí tốt hơn:public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);
Patrik Melander

1
Tôi không nghĩ phương thức mở rộng này sẽ âm thầm trả về falsechuỗi null. Đó là lý do tại sao tôi đề xuất phiên bản ++ (thậm chí tốt hơn tốt hơn) : public static bool IsValidEmailAddress(this string address) => new EmailAddressAttribute().IsValid(address ?? throw new ArgumentNullException());. Bây giờ tôi sẽ đi và tìm thấy Nhà thờ Cải cách của những người lập trình tốt hơn nữa.
Marc.2377

41

.net 4.5 đã thêm System.ComponentModel.DataAnnotations.EmailAddressAttribution

Bạn có thể duyệt qua nguồn của EmailAddressAttribution , đây là Regex mà nó sử dụng trong nội bộ:

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
Thật không may, EmaillAddressAttribution cho phép Ñ không phải là ký tự hợp lệ cho email
BZ

16
@BZ Đúng vậy. Tại sao bạn nghĩ rằng nó không phải là?
Casey

@Chad Grant: Đây là phiên bản C #. Bạn có thể vui lòng cung cấp một VB.Net. Bởi vì điều đó sẽ thoát khỏi các characers như \\ to \ hoặc bạn có thể cung cấp một chuỗi nguyên văn.
Nikhil Agrawal

3
Điều này hoạt động, nhưng đừng quên RegexOptions.IgnoreCasevì mẫu này không cho phép chữ in hoa rõ ràng!
Chris

1
Lưu ý rằng Regex rất có chủ ý: "Thuộc tính này cung cấp xác thực email phía máy chủ tương đương với xác thực jquery và do đó chia sẻ cùng một biểu thức chính quy".
Ohad Schneider

38

Tôi lấy câu trả lời của Phil từ số 1 và tạo ra lớp này. Gọi nó như thế này:bool isValid = Validator.EmailIsValid(emailString);

Đây là lớp học:

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
Chỉ là một cái nhỏ, nhưng tôi sẽ sử dụng: return (! String.IsNullOrEmpty (emailAddress)) && ValidEmailRegex.IsMatch (emailAddress);
Marc

Đây chỉ là kinh dị :)
Alexandru Dicu

31

Cá nhân, tôi sẽ nói rằng bạn chỉ cần đảm bảo có biểu tượng @ trong đó, có thể là a. tính cách. Có nhiều biểu thức bạn có thể sử dụng với độ chính xác khác nhau, nhưng tôi nghĩ rằng hầu hết các địa chỉ này đều bỏ qua các địa chỉ email hợp lệ hoặc để những địa chỉ không hợp lệ thông qua. Nếu mọi người muốn đặt một địa chỉ email giả, họ sẽ đặt một địa chỉ giả. Nếu bạn cần xác minh rằng địa chỉ email là hợp pháp và người đó kiểm soát địa chỉ email đó, thì bạn sẽ cần gửi cho họ một email có liên kết được mã hóa đặc biệt để họ có thể xác minh rằng đó thực sự là một địa chỉ thực.


6
Cá nhân tôi nghĩ rằng bạn nên làm một chút xác nhận hơn thế. Ai đó bị ràng buộc thử địa chỉ email của Bobby Table hoặc tệ hơn.
Luke Quinane

31
Có gì sai với địa chỉ email của bảng bgie nếu bạn đang sử dụng báo cáo đã chuẩn bị. Chúng ta đang nói về các địa chỉ email hợp lệ, không phải những thứ khác không liên quan đến những gì tạo thành một địa chỉ email hợp lệ, như cách thực hiện đúng các truy vấn SQL để bạn không gặp vấn đề về SQL.
Kibbee

Tôi đoán bạn không biết ai đó sẽ đưa vào đó nhưng một kẻ độc hại biết rằng giá trị cuối cùng có thể được đưa vào hệ thống thư của bạn. Tôi chỉ muốn phòng thủ theo chiều sâu và nghiêm ngặt hơn một chút.
Luke Quinane

10
Đó là điều khiến hệ thống thư phải lo lắng. Tôi sẽ không đi từ chối các địa chỉ email hoàn toàn hợp lệ chỉ vì đó có thể là vấn đề bảo mật với một số hệ thống khác. Nếu tất cả các nhu cầu máy chủ email của bạn là một địa chỉ email không đúng định dạng để gây ra sự cố bảo mật, có lẽ bạn nên chuyển sang một máy chủ khác.
Kibbee

4
Bảo vệ theo chiều sâu chỉ hoạt động nếu mỗi cấp của hành động bảo mật của bạn không bị thối. Một lớp thối có nghĩa là bạn làm hỏng toàn bộ hành tây. Từ chối "foo@example.com.au" bởi vì bạn muốn bảo vệ chống lại các lỗ hổng trong mã hóa luật pháp của Sun không có ý nghĩa gì, phải không? Đừng cười, nó đã xảy ra với tôi. Lý do tôi ở đây nhận xét là Medicare Australia không cho phép địa chỉ ".au", chỉ ".com". Đồng thời đọc Mark Swanson, "Cách không xác thực email", mdswanson.com/blog/2013/10/14/ mẹo
ManicDee

17

Tôi nghĩ rằng cách tốt nhất là như sau:

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

Bạn có thể có hàm tĩnh này trong một lớp chung.


Câu trả lời này không chấp nhận một địa chỉ có TLD trong phần tên miền.
Simone

15

Mã ngắn và chính xác

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
Cảm ơn giải pháp
Jack Gajanan

Tôi đã phải thay đổi bool tĩnh IsValidEmail (email chuỗi này) thành bool tĩnh tĩnh IsValidEmail (email chuỗi) để tránh NÀY: stackoverflow.com/questions/10412233/
trộm

. @Goner Doug, functionlity này sẽ làm việc như thế này (bool cờ = EmailAddress.IsValidEmail ())
Naveen

2
"NÀY" cần được xóa để tránh gây ra sự cố trình biên dịch khi thêm vào biểu mẫu của tôi.
Goner Doug

@Goner Doug, chức năng của nó sẽ hoạt động như thế này. chuỗi email = "abc@xyz.com"; if (email.IsValidEmail ()) {trả về false; } other {return true;}
Naveen

14

Cách thanh lịch nhất là sử dụng các phương thức được xây dựng của .Net.

Những phương pháp sau:

  • Được thử và kiểm tra. Những phương pháp này được sử dụng trong các dự án chuyên nghiệp của riêng tôi.

  • Sử dụng các biểu thức chính quy trong nội bộ, đáng tin cậy và nhanh chóng.

  • Được sản xuất bởi Microsoft cho C #. Không cần phải phát minh lại bánh xe.

  • Trả về một kết quả bool. Đúng có nghĩa là email hợp lệ.

Đối với người dùng .Net 4.5 trở lên

Thêm tài liệu tham khảo này vào dự án của bạn:

System.ComponentModel.DataAnnotations

Bây giờ bạn có thể sử dụng mã sau đây:

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

Ví dụ sử dụng

Dưới đây là một số phương pháp để khai báo:

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;

}

... và mã chứng minh chúng hoạt động:

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

}

Ngoài ra, ví dụ này:

  • Mở rộng ra ngoài thông số kỹ thuật vì một chuỗi đơn được sử dụng để chứa 0, một hoặc nhiều địa chỉ email được đặt bởi dấu chấm phẩy ; .
  • Trình bày rõ ràng cách sử dụng phương thức IsValid của đối tượng EmailAddressAttribution.

Thay thế, đối với người dùng phiên bản .Net nhỏ hơn 4,5

Đối với các tình huống .Net 4.5 không khả dụng, tôi sử dụng giải pháp sau:

Cụ thể, tôi sử dụng:

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 Tôi chưa thấy câu trả lời EmailAddressAttribution và không có câu trả lời nào sử dụng MailAddress () mới với kiểm tra đầu vào == .Địa chỉ vì vậy tôi nghĩ nó khá hữu ích. Không đọc bình luận, câu trả lời được chấp nhận là khá sai. MailAddress mới ("Foobar some@thing.com") chứng minh điều đó.
Ngày

@Jan fwiw, Manik đã đánh bại Knickerless EmailAddressAttributechỉ sau chưa đầy bốn tháng, mặc dù điều này không bắt được nullvấn đề.
ruffin

7

Thành thật mà nói, trong mã sản xuất, điều tốt nhất tôi làm là kiểm tra một @biểu tượng.

Tôi không bao giờ ở một nơi để xác nhận hoàn toàn các email. Bạn biết làm thế nào tôi thấy nếu nó thực sự hợp lệ? Nếu nó được gửi đi. Nếu nó không, nó xấu, nếu nó đã làm, cuộc sống là tốt. Đó là tất cả những gì tôi cần biết.


6

Tôi thấy regex này là một sự đánh đổi tốt giữa việc kiểm tra một cái gì đó hơn là chỉ dấu @ và chấp nhận các trường hợp cạnh kỳ lạ:

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

Nó ít nhất sẽ khiến bạn đặt một cái gì đó xung quanh dấu @ và đặt ít nhất một miền trông bình thường.


Tôi đã đưa ra cùng một biểu thức chính thức;) Mặc dù vậy, nó cho phép các trình duyệt không hợp lệ
Stefan

Câu trả lời này không chấp nhận TLD trong phần tên miền.
Simone

@Simone có lẽ không ai có địa chỉ email với TLD trong phần tên miền mặc dù trên thực tế: serverfault.com/a/721929/167961 lưu ý trong các nhận xét có thể bị cấm trong những ngày này
Matthew Lock

@MatthewLock Nó có thể là một địa chỉ mạng nội bộ không? Giống như bob@companyinternal?
Simone

@Simone có ai trong đời thực sử dụng sơ đồ đó không?
Khóa Matthew

4

Xác thực địa chỉ email không dễ dàng như nó có vẻ. Về mặt lý thuyết, thực tế không thể xác thực hoàn toàn một địa chỉ email chỉ bằng một biểu thức thông thường.

Kiểm tra bài đăng trên blog của tôi về nó để thảo luận về chủ đề này và triển khai F # bằng cách sử dụng FParsec. [/ shaming_plug]


1
Tôi thích bạn danh sách các phương pháp thay thế; rất thú vị.
Luke Quinane

1
Bài báo thú vị. Nhưng nghiêm túc ai là người đưa ý kiến, và những người lồng vào đó, trong địa chỉ email?
Matthew Khóa

3
@matthew Tôi không biết tại sao IETF thậm chí còn cho phép điều đó, nhưng điều đó là có thể , vì vậy việc xác nhận kỹ lưỡng phải tính đến nó.
Mauricio Scheffer

4

Đây là câu trả lời của tôi - Giải pháp của Phil không thành công cho các tên miền đơn như "someone@q.com". Dù bạn có tin hay không, điều đó được sử dụng =) (ví dụ, đi đến centurylink).

Câu trả lời của Phil cũng sẽ chỉ hoạt động với tiêu chuẩn PCRE ... vì vậy C # sẽ lấy nó, nhưng javascript sẽ đánh bom. Nó quá phức tạp đối với javascript. Vì vậy, bạn không thể sử dụng giải pháp của Phil cho các thuộc tính xác thực mvc.

Đây là regex của tôi. Nó sẽ hoạt động độc đáo với các thuộc tính xác thực MVC.
- Mọi thứ trước khi @ được đơn giản hóa, để ít nhất javascript sẽ hoạt động. Tôi ổn khi xác nhận thư giãn ở đây miễn là máy chủ trao đổi không cung cấp cho tôi 5.1.3. - Mọi thứ sau @ là giải pháp của Phil được sửa đổi cho các tên miền đơn.

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

Đối với những người đề xuất sử dụng system.net.mail MailMessage (), điều đó là CÁCH để linh hoạt. Chắc chắn, C # sẽ chấp nhận email, nhưng sau đó máy chủ trao đổi sẽ đánh bom với lỗi thời gian chạy 5.1.3 ngay khi bạn cố gắng gửi email.


đó dường như là câu trả lời chu đáo / hợp lý / thực tế nhất, cảm ơn Ralph!
Fattie

Đây là câu trả lời tốt nhất cho đến nay! Tôi không thể tin rằng một giải pháp tồi tệ chấp nhận basket@ballnhư một địa chỉ email hợp lệ đã có được câu trả lời chính xác cũng như tất cả các upvote đó. Dù sao cũng cảm ơn bạn!
thảm họa

Cảm ơn đây là giải pháp tốt nhất và nên được chấp nhận câu trả lời.
Bat_Programmer

3

Nếu bạn thực sự và tôi có nghĩa là thực sự muốn biết nếu một địa chỉ email là hợp lệ ... hãy yêu cầu trao đổi thư để chứng minh nó, không cần regex. Tôi có thể cung cấp mã nếu được yêu cầu.

Các bước chung như sau: 1. địa chỉ email có một phần tên miền không? (chỉ mục của @> 0) 2. sử dụng truy vấn DNS hỏi xem tên miền có bộ trao đổi thư 3. mở kết nối tcp với bộ trao đổi thư 4. sử dụng giao thức smtp, mở thư tới máy chủ bằng địa chỉ email làm người nhận 5. phân tích phản hồi của máy chủ. 6. bỏ tin nhắn nếu bạn thực hiện đến nay, mọi thứ đều tốt.

Đây là như bạn có thể tưởng tượng, thời gian rất tốn kém khôn ngoan và dựa vào smtp, nhưng nó hoạt động.


Bạn đã tạo hàng giả, sơ khai và / hoặc giả cho các giao diện đó chưa?
Đánh dấu A

1
Điều đó sẽ không làm việc. Giao thức smtp để xác minh địa chỉ email đã bị phản đối / không được sử dụng. Nó được coi là thực hành xấu để cho phép trên các máy chủ thư vì những kẻ gửi thư rác sử dụng chức năng đó.
Chad Grant

Tôi sẽ giữ đề xuất của bạn cho đến điểm 2. Cách chứng minh tương lai nhiều hơn là kiểm tra mẫu tên miền đã biết.
Simone

Nitpicking, nhưng định nghĩa "có một trao đổi thư" ? Nếu không có bản ghi MX nào tồn tại, SMTP sẽ quay trở lại bản ghi A / AAAA, theo RFC2821 / 5321. Nếu bản ghi MX tồn tại, nó vẫn có thể không biểu thị bộ trao đổi thư tồn tại (RFC7505). Thực sự, cách duy nhất là gửi cho họ một thư có liên kết kêu gọi hành động và chờ họ trả lời ...
jimbobmcgee

2

Nói chung, một biểu thức thông thường để xác thực địa chỉ email không phải là một điều dễ dàng để đưa ra; tại thời điểm viết bài này, cú pháp của một địa chỉ email phải tuân theo số lượng tiêu chuẩn tương đối cao và việc thực hiện tất cả chúng trong một biểu thức chính quy là thực tế không khả thi!

Tôi thực sự khuyên bạn nên dùng thử EmailVerify.NET , một thư viện .NET trưởng thành có thể xác thực các địa chỉ email theo sau tất cả các tiêu chuẩn IETF hiện tại (RFC 1123, RFC 2821, RFC 2822, RFC 3696, RFC 4291, RFC 5321 và RFC 5322) , kiểm tra các bản ghi DNS liên quan, kiểm tra xem các hộp thư đích có thể chấp nhận tin nhắn hay không và thậm chí có thể biết liệu một địa chỉ đã cho có dùng được hay không.

Tuyên bố miễn trừ trách nhiệm: Tôi là nhà phát triển chính cho thành phần này.


Ấn tượng! "Tiếp theo, nó cố gắng liên hệ với bộ trao đổi thư chịu trách nhiệm về địa chỉ email đã cho và bắt đầu hộp thoại SMTP giả với máy chủ đó, mô phỏng một máy chủ thư thật. Cách này đảm bảo rằng máy chủ có thể xử lý email cho địa chỉ. trả lại câu trả lời dương tính giả như một biện pháp bảo vệ chống lại những kẻ gửi thư rác: để khắc phục vấn đề này, EmailVerify cho .NET cuối cùng đã cố gắng truy vấn bộ trao đổi thư mục tiêu nhiều lần với các địa chỉ bịa đặt khác nhau. "
Matthew Lock

Cảm ơn, @MatthewLock;)
Efran Cobisi

Đẹp, nhưng tôi chỉ thấy phiên bản trả tiền. Bất kỳ kế hoạch cho một phiên bản cộng đồng / OpenSource?
Ohad Schneider

1
@OhadSchneider Có: chúng tôi đang cung cấp phiên bản miễn phí của công nghệ xác thực email của chúng tôi thông qua Verifalia, dịch vụ xác minh email SaaS của chúng tôi . Verifalia đi kèm với SDK miễn phí và mã nguồn mở cho các nền tảng phát triển phần mềm chính, bao gồm .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;
        }

Nó sẽ không xác nhận a@b.info là một địa chỉ email hợp lệ.
Ray Cheng

2

Trong trường hợp bạn đang sử dụng FluentValidation, bạn có thể viết một cái gì đó đơn giản như thế này:

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

một chút sửa đổi để trả lời @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;
  }
}

Điều này dường như không giúp ... Console.WriteLine(MailAddress("asdf@asdf.").Address);xuất ra "asdf @ asdf.", Không hợp lệ.
Langdon

.net dường như có định nghĩa riêng về giá trị. thảo luận
chờ

2

Có rất nhiều câu trả lời mạnh mẽ ở đây. Tuy nhiên, tôi khuyên chúng ta nên lùi lại một bước. @Cogwheel trả lời câu hỏi https://stackoverflow.com/a/1374644/388267 . Tuy nhiên, nó có thể tốn kém trong một kịch bản xác nhận hàng loạt, nếu nhiều địa chỉ email được xác thực là không hợp lệ. Tôi đề nghị rằng chúng tôi sử dụng một chút logic trước khi chúng tôi tham gia vào khối thử bắt của anh ấy. Tôi biết rằng đoạn mã sau có thể được viết bằng RegEx nhưng điều đó có thể tốn kém cho các nhà phát triển mới hiểu. Đây là giá trị gấp đôi của tôi:

    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

Câu trả lời được bình chọn nhiều nhất từ ​​@Cogwheel là câu trả lời tốt nhất tuy nhiên tôi đã cố gắng thực hiện trim()phương thức chuỗi để nó sẽ cắt tất cả khoảng trắng của người dùng từ đầu chuỗi đến hết. Kiểm tra mã dưới đây cho ví dụ đầy đủ-

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

Rủi ro của điều này là bạn đang xác nhận một địa chỉ thư điện tử khác với nguồn, khiến bạn nghĩ rằng bạn có thể gửi thư đến (trong trường hợp này) phiên bản chưa được đánh giá của địa chỉ thư điện tử được chỉ định. Một cách tiếp cận tốt hơn sẽ là tạo một phương thức riêng biệt SanitizeEmail(string email), sử dụng kết quả của phương thức đó để xác nhận và gửi email đến.
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);
}

1

Kiểm tra chuỗi email có đúng định dạng hoặc định dạng sai bằng cách 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

/ Sử dụng Regex nội bộ được sử dụng trong việc tạo "EmailAddressAttribution ();" thành phần trong .Net4.5 >>> sử dụng System.ComponentModel.DataAnnotations; // Để xác thực một địa chỉ email ...... Đã kiểm tra và làm việc.

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

Ngoài ra, bạn có thể sử dụng điều này:

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


nó nói đúng với email này: "Fulya_42_@hotmail.coö" và nó ném lỗi tại aprill api
MonsterMMORPG

1
Đầu tiên, email là hợp lệ wrt example@example.co hoặc example@example.com .... Email có tất cả các chuỗi và tiêu chí hợp lệ ngoại trừ ký tự cuối cùng "ö" và bạn có thể dễ dàng thêm một điều kiện đơn giản để xác thực ký tự đó . Thứ hai, tôi không chắc chắn về lỗi api bắt buộc đó, bạn có thể muốn xác minh phương pháp sử dụng bcos của mình. Tôi đã sử dụng xác nhận này trên một số môi trường / api khác và nó rất tốt với tôi.
Aina Ademola C

1

Tôi rút gọn câu trả lời của Poyson 1 như vậy:

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

Cách đơn giản để xác định emailid có hợp lệ hay không.

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ó vấn đề về văn hóa trong regex trong C # chứ không phải js. Vì vậy, chúng ta cần sử dụng regex trong chế độ Hoa Kỳ để kiểm tra email. Nếu bạn không sử dụng chế độ ECMAScript, các ký tự đặc biệt ngôn ngữ của bạn sẽ ngụ ý trong AZ với 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)

1

Tôi đã kết thúc bằng cách sử dụng regex này, vì nó xác nhận thành công dấu phẩy, nhận xét, ký tự Unicode và địa chỉ tên miền IP (v4).

Địa chỉ hợp lệ sẽ là:

"" @ example.org

(comment)test@example.org

тест@example.org

ტესტი @ example.org

kiểm tra @ [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

Một cách đơn giản mà không cần sử dụng Regex (điều mà tôi không thích vì khả năng đọc kém):

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

Ví dụ:

  • 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

Điều này có nghĩa là đơn giản và do đó, nó không giải quyết các trường hợp hiếm gặp như email có tên miền có dấu cách chứa khoảng trắng (thường được cho phép), email có địa chỉ IPv6, v.v.


1

Đây là một câu trả lời cho câu hỏi của bạn để bạn kiểm tra.

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

Dựa trên câu trả lời của @Cogwheel, tôi muốn chia sẻ một giải pháp sửa đổi hoạt động cho SSIS và "Thành phần tập lệnh":

  1. Đặt "Thành phần tập lệnh" vào kết nối luồng dữ liệu của bạn và sau đó mở nó.
  2. Trong phần "Cột đầu vào", đặt trường chứa Địa chỉ E-Mail thành "ReadWrite" (trong ví dụ 'fieldName').
  3. Quay trở lại phần "Tập lệnh" và bấm vào "Chỉnh sửa tập lệnh". Sau đó, bạn cần phải đợi sau khi mã mở.
  4. Đặt mã này theo đúng phương pháp:

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

Sau đó, bạn có thể sử dụng Phân chia có điều kiện để lọc tất cả các bản ghi không hợp lệ hoặc bất cứ điều gì bạn muốn làm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.