it-swarm-vi.com

Làm cách nào để xác thực địa chỉ email bằng biểu thức chính quy?

Trong những năm qua, tôi đã dần dần phát triển biểu thức chính quy xác nhận chính xác các địa chỉ email MOST, giả sử họ không sử dụng địa chỉ IP làm phần máy chủ.

Tôi sử dụng nó trong một số chương trình PHP và nó hoạt động hầu hết thời gian. Tuy nhiên, thỉnh thoảng tôi được liên lạc bởi một người gặp sự cố với trang web sử dụng nó và cuối cùng tôi phải điều chỉnh (gần đây nhất tôi nhận ra rằng tôi không cho phép TLD 4 ký tự).

Biểu thức chính quy tốt nhất bạn có hoặc đã thấy để xác thực email là gì?

Tôi đã thấy một số giải pháp sử dụng các hàm sử dụng một số biểu thức ngắn hơn, nhưng tôi muốn có một biểu thức phức tạp dài trong một hàm đơn giản thay vì một vài biểu thức ngắn trong một hàm phức tạp hơn.

3051
acrosman

regex hoàn toàn tuân thủ RFC 822 không hiệu quả và tối nghĩa vì độ dài của nó. May mắn thay, RFC 822 đã được thay thế hai lần và thông số kỹ thuật hiện tại cho các địa chỉ email là RFC 5322 . RFC 5322 dẫn đến một regex có thể được hiểu nếu được nghiên cứu trong vài phút và đủ hiệu quả để sử dụng thực tế.

Có thể tìm thấy một regex tuân thủ RFC 5322 ở đầu trang tại http://emailregex.com/ nhưng sử dụng mẫu địa chỉ IP trôi nổi trên internet với lỗi cho phép 00 cho bất kỳ dấu nào giá trị thập phân byte trong một địa chỉ được phân cách bằng dấu chấm, là bất hợp pháp. Phần còn lại của nó có vẻ phù hợp với ngữ pháp RFC 5322 và vượt qua một số bài kiểm tra bằng cách sử dụng grep -Po, bao gồm các trường hợp tên miền, địa chỉ IP, tên xấu và tên tài khoản có và không có dấu ngoặc kép.

Sửa lỗi 00 trong mẫu IP, chúng tôi có được một biểu thức chính quy hoạt động và khá nhanh. (Quét phiên bản kết xuất, không phải đánh dấu, cho mã thực tế.)

(?: [a-z0-9! # $% & '* +/=? ^ _ `{|} ~ -] + (?: \. [a-z0-9! # $% &' * +/=? ^ _ `{|} ~ -] +) * |" (?: [\ x01-\x09\x0b\x0c\x0e-\x7f]) * ") @ (?: (?: [a-z0-9] (?: [a-z0-9 -] * [a-z0 -9])? \.) + [A-z0-9] (?: [A-z0-9 -] * [a-z0-9])? |\[(? :(? :( 2 (5 [0-5] | [0-4] [0-9]) | 1 [0-9] [0-9] | [1-9]? [0-9])) \.) {3} ( ? :( 2 (5 [0-5] | [0-4] [0-9]) | 1 [0-9] [0-9] | [1-9]? [0-9]) | [ a-z0-9 -] * [a-z0-9]: (?: [\ x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f] |\[\ x01-\x09\x0b\x0c\x0e-\x7f]) +) \])

Đây là sơ đồ của máy trạng thái hữu hạn cho regrec ở trên rõ ràng hơn chính regrec  enter image description here

Các mẫu phức tạp hơn trong Perl và PCRE (thư viện regex được sử dụng, ví dụ như trong PHP) có thể phân tích chính xác RFC 5322 mà không gặp trở ngại . Python và C # cũng có thể làm điều đó, nhưng chúng sử dụng một cú pháp khác với hai cái đầu tiên. Tuy nhiên, nếu bạn buộc phải sử dụng một trong nhiều ngôn ngữ phù hợp với mô hình ít mạnh mẽ hơn, thì tốt nhất là sử dụng một trình phân tích cú pháp thực sự.

Điều quan trọng là phải hiểu rằng việc xác thực nó theo RFC hoàn toàn không cho bạn biết địa chỉ đó có thực sự tồn tại ở miền được cung cấp hay không, hoặc người nhập địa chỉ có phải là chủ sở hữu thực sự hay không. Mọi người đăng ký người khác để gửi danh sách theo cách này mọi lúc. Việc sửa lỗi yêu cầu một loại xác thực fancier liên quan đến việc gửi địa chỉ đó một tin nhắn bao gồm mã thông báo xác nhận có nghĩa được nhập trên cùng một trang web như địa chỉ. 

Mã xác nhận là cách duy nhất để biết bạn có địa chỉ của người nhập. Đây là lý do tại sao hầu hết các danh sách gửi thư hiện sử dụng cơ chế đó để xác nhận đăng ký. Rốt cuộc, bất kỳ ai cũng có thể đặt [email protected], và điều đó thậm chí sẽ phân tích thành hợp pháp, nhưng không có khả năng đó là người ở đầu kia.

Đối với PHP, bạn nên không sử dụng mẫu được cung cấp trong Xác thực địa chỉ E-mail bằng PHP, đúng cách từ đó tôi trích dẫn:

Có một số nguy hiểm rằng việc sử dụng phổ biến và mã hóa cẩu thả trên diện rộng sẽ thiết lập một tiêu chuẩn thực tế cho các địa chỉ email hạn chế hơn so với tiêu chuẩn chính thức được ghi lại.

Điều đó không tốt hơn tất cả các mẫu phi RFC khác. Nó thậm chí còn đủ thông minh để xử lý thậm chí RFC 822 , huống chi là RFC 5322. Cái này , tuy nhiên, là.

Nếu bạn muốn nhận được ưa thích và mô phạm, thực hiện một công cụ trạng thái hoàn chỉnh . Một biểu thức chính quy chỉ có thể hoạt động như một bộ lọc thô sơ. Vấn đề với các biểu thức thông thường là việc nói với ai đó rằng địa chỉ email hoàn toàn hợp lệ của họ là không hợp lệ (dương tính giả) vì biểu thức thông thường của bạn không thể xử lý nó chỉ là thô lỗ và bất lịch sự từ quan điểm của người dùng. Một công cụ trạng thái cho mục đích có thể xác nhận và thậm chí chính xác các địa chỉ e-mail mà nếu không được coi là không hợp lệ vì nó tách rời địa chỉ e-mail theo từng RFC. Điều này cho phép trải nghiệm có khả năng làm hài lòng hơn, như

Địa chỉ email được chỉ định 'myemail @ address, com' không hợp lệ. Ý bạn là '[email protected]'?

Xem thêm Xác thực địa chỉ email , bao gồm cả các nhận xét. Hoặc So sánh địa chỉ email xác thực biểu thức chính quy .

 Regular expression visualization

Bản trình diễn Debuggex

2201
bortzmeyer

You should not use regular expressions to validate email addresses.

Instead, use the MailAddress class, like this:

try {
    address = new MailAddress(address).Address;
} catch(FormatException) {
    //address is invalid
}

The MailAddress class uses a BNF parser to validate the address in full accordance with RFC822.

If you really want to use a regex, here it is:

(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:
\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(
?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ 
\t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\0
31]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\
](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+
(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:
(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)
?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\
r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[
 \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)
?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t]
)*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[
 \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*
)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)
*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+
|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r
\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t
]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031
]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](
?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?
:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?
:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?
:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?
[ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] 
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|
\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>

@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"
(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t]
)*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?
:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[
\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-
\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(
?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;
:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([
^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\"
.\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\
]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\
[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\
r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] 
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]
|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \0
00-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\
.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,
;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?
:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[
^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]
]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s*(
?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(
?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[
\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t
])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t
])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?
:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|
\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:
[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\
]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)
?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["
()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)
?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>

@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[
 \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,
;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t]
)*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:
\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[
"()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])
*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])
+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\
.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(
?:\r\n)?[ \t])*))*)?;\s*)
723
SLaks

Câu hỏi này được hỏi rất nhiều, nhưng tôi nghĩ bạn nên lùi lại và tự hỏi tại sao bạn muốn xác thực địa chỉ email một cách tổng hợp? Lợi ích thực sự là gì?

  • Nó sẽ không bắt lỗi chính tả.
  • Nó không ngăn mọi người nhập địa chỉ email không hợp lệ hoặc bịa đặt hoặc nhập địa chỉ của người khác. 

Nếu bạn muốn xác thực rằng một email là chính xác, bạn không có lựa chọn nào hơn là gửi email xác nhận và yêu cầu người dùng trả lời. Trong nhiều trường hợp, bạn sẽđể gửi thư xác nhận dù sao vì lý do bảo mật hoặc vì lý do đạo đức (vì vậy bạn không thể đăng ký một người nào đó theo dịch vụ trái với ý muốn của họ).

518
JacquesB

Nó phụ thuộc vào ý của bạn là gì tốt nhất: Nếu bạn đang nói về việc nắm bắt mọi địa chỉ email hợp lệ, hãy sử dụng như sau:

(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:
\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(
?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ 
\t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\0
31]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\
](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+
(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:
(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)
?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\
r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[
 \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)
?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t]
)*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[
 \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*
)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)
*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+
|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r
\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t
]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031
]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](
?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?
:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?
:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?
:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?
[ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] 
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|
\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>
@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"
(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t]
)*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?
:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[
\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-
\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(
?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;
:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([
^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\"
.\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\
]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\
[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\
r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] 
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]
|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \0
00-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\
.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,
;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?
:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[
^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]
]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s*(
?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(
?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[
\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t
])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t
])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?
:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|
\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:
[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\
]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)
?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["
()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)
?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>
@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[
 \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,
;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t]
)*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:
\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[
"()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])
*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])
+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\
.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(
?:\r\n)?[ \t])*))*)?;\s*)

( http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html ) Nếu bạn đang tìm kiếm một cái gì đó đơn giản hơn nhưng sẽ bắt được hầu hết các địa chỉ email hợp lệ : 

"^[a-zA-Z0-9_.+-][email protected][a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"

EDIT: Từ liên kết:

Biểu thức chính quy này sẽ chỉ xác nhận các địa chỉ đã có bất kỳ nhận xét nào bị tước và thay thế bằng khoảng trắng (điều này được thực hiện bởi mô-đun).

327
Good Person

Tất cả phụ thuộc vào mức độ chính xác mà bạn muốn trở thành. Đối với mục đích của tôi, nơi tôi chỉ cố gắng tránh những thứ như bob @ aol.com (khoảng trắng trong email) hoặc steve (không có tên miền nào) hoặc [email protected] (không có thời gian trước khi .com)

/^\[email protected]\S+\.\S+$/

Chắc chắn, nó sẽ khớp với những thứ không phải là địa chỉ email hợp lệ, nhưng đó là vấn đề chơi theo quy tắc 90/10. 

317
Andy Lester

[CẬP NHẬT] Tôi đã đối chiếu mọi thứ tôi biết về xác thực địa chỉ email tại đây: http://isemail.info , giờ đây không chỉ xác thực mà còn chẩn đoán sự cố với địa chỉ email. Tôi đồng ý với nhiều ý kiến ​​ở đây rằng xác nhận chỉ là một phần của câu trả lời; xem bài luận của tôi tại http://isemail.info/about .

is_email () vẫn còn, theo như tôi biết, trình xác nhận duy nhất sẽ cho bạn biết chắc chắn liệu một chuỗi đã cho có phải là một địa chỉ email hợp lệ hay không. Tôi đã tải lên một phiên bản mới tại http://isemail.info/

Tôi đã đối chiếu các trường hợp thử nghiệm từ Cal Henderson, Dave Child, Phil Haack, Doug Lovell, RFC5322 và RFC 3696. Có tất cả 275 địa chỉ kiểm tra. Tôi đã chạy tất cả các bài kiểm tra này chống lại tất cả các trình xác nhận miễn phí mà tôi có thể tìm thấy.

Tôi sẽ cố gắng cập nhật trang này khi mọi người nâng cao trình xác nhận của họ. Cảm ơn Cal, Michael, Dave, Paul và Phil đã giúp đỡ và hợp tác trong việc biên soạn các bài kiểm tra này và phê bình mang tính xây dựng của trình xác nhận của riêng tôi .

Mọi người nên biết về errata so với RFC 3696 nói riêng. Ba trong số các ví dụ kinh điển trên thực tế là các địa chỉ không hợp lệ. Và độ dài tối đa của một địa chỉ là 254 hoặc 256 ký tự, không 320.

285
Dominic Sayers

Mỗi thông số HTML5 của W3C :

^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-][email protected][a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$

Bối cảnh:

Địa chỉ e-mail hợp lệ là một chuỗi phù hợp với sản xuất ABNF [Tiết].

Lưu ý: Yêu cầu này là vi phạm cố ý of RFC 5322 , định nghĩa cú pháp cho các địa chỉ email đồng thời quá nghiêm ngặt (trước cả ký tự của @ @) mơ hồ (sau ký tự của @ @) và quá lỏng lẻo (cho phép nhận xét, ký tự khoảng trắng và chuỗi trích dẫn trong cách cư xử không quen thuộc với hầu hết người dùng) được sử dụng thực tế ở đây.

Biểu thức chính quy tương thích với JavaScript và Perl sau đây là cách triển khai định nghĩa trên.

/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-][email protected][a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
259
Josh Stodola

Nó dễ dàng trong Perl 5.10 hoặc mới hơn:

/(?(DEFINE)
   (?<address>         (?&mailbox) | (?&group))
   (?<mailbox>         (?&name_addr) | (?&addr_spec))
   (?<name_addr>       (?&display_name)? (?&angle_addr))
   (?<angle_addr>      (?&CFWS)? < (?&addr_spec) > (?&CFWS)?)
   (?<group>           (?&display_name) : (?:(?&mailbox_list) | (?&CFWS))? ;
                                          (?&CFWS)?)
   (?<display_name>    (?&phrase))
   (?<mailbox_list>    (?&mailbox) (?: , (?&mailbox))*)

   (?<addr_spec>       (?&local_part) \@ (?&domain))
   (?<local_part>      (?&dot_atom) | (?&quoted_string))
   (?<domain>          (?&dot_atom) | (?&domain_literal))
   (?<domain_literal>  (?&CFWS)? \[ (?: (?&FWS)? (?&dcontent))* (?&FWS)?
                                 \] (?&CFWS)?)
   (?<dcontent>        (?&dtext) | (?&quoted_pair))
   (?<dtext>           (?&NO_WS_CTL) | [\x21-\x5a\x5e-\x7e])

   (?<atext>           (?&ALPHA) | (?&DIGIT) | [!#\$%&'*+-/=?^_`{|}~])
   (?<atom>            (?&CFWS)? (?&atext)+ (?&CFWS)?)
   (?<dot_atom>        (?&CFWS)? (?&dot_atom_text) (?&CFWS)?)
   (?<dot_atom_text>   (?&atext)+ (?: \. (?&atext)+)*)

   (?<text>            [\x01-\x09\x0b\x0c\x0e-\x7f])
   (?<quoted_pair>     \\ (?&text))

   (?<qtext>           (?&NO_WS_CTL) | [\x21\x23-\x5b\x5d-\x7e])
   (?<qcontent>        (?&qtext) | (?&quoted_pair))
   (?<quoted_string>   (?&CFWS)? (?&DQUOTE) (?:(?&FWS)? (?&qcontent))*
                        (?&FWS)? (?&DQUOTE) (?&CFWS)?)

   (?<Word>            (?&atom) | (?&quoted_string))
   (?<phrase>          (?&Word)+)

   # Folding white space
   (?<FWS>             (?: (?&WSP)* (?&CRLF))? (?&WSP)+)
   (?<ctext>           (?&NO_WS_CTL) | [\x21-\x27\x2a-\x5b\x5d-\x7e])
   (?<ccontent>        (?&ctext) | (?&quoted_pair) | (?&comment))
   (?<comment>         \( (?: (?&FWS)? (?&ccontent))* (?&FWS)? \) )
   (?<CFWS>            (?: (?&FWS)? (?&comment))*
                       (?: (?:(?&FWS)? (?&comment)) | (?&FWS)))

   # No whitespace control
   (?<NO_WS_CTL>       [\x01-\x08\x0b\x0c\x0e-\x1f\x7f])

   (?<ALPHA>           [A-Za-z])
   (?<DIGIT>           [0-9])
   (?<CRLF>            \x0d \x0a)
   (?<DQUOTE>          ")
   (?<WSP>             [\x20\x09])
 )

 (?&address)/x
197
Abigail

Tôi sử dụng

^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$

Cái nào được sử dụng trong ASP.NET bởi RoutExpressionValidator.

148

Không biết về điều tốt nhất, nhưng điều này ít nhất là chính xác, miễn là các địa chỉ bị xóa bình luận và thay thế bằng khoảng trắng.

Nghiêm túc. Bạn nên sử dụng một thư viện đã được viết để xác nhận email. Cách tốt nhất có lẽ là chỉ cần gửi e-mail xác minh đến địa chỉ đó.

140
Chris Vest

Các địa chỉ email tôi muốn xác thực sẽ được sử dụng bởi một ứng dụng web ASP.NET sử dụng không gian tên System.Net.Mail để gửi email đến danh sách mọi người. Vì vậy, thay vì sử dụng một số biểu thức chính quy rất phức tạp, tôi chỉ cố gắng tạo một cá thể MailAddress từ địa chỉ. Trình kết hợp MailAddress sẽ đưa ra một ngoại lệ nếu địa chỉ không được hình thành đúng. Bằng cách này, tôi biết tôi ít nhất có thể lấy email ra khỏi cửa. Tất nhiên đây là xác nhận phía máy chủ nhưng tối thiểu bạn vẫn cần điều đó.

protected void emailValidator_ServerValidate(object source, ServerValidateEventArgs args)
{
    try
    {
        var a = new MailAddress(txtEmail.Text);
    }
    catch (Exception ex)
    {
        args.IsValid = false;
        emailValidator.ErrorMessage = "email: " + ex.Message;
    }
}
108
davcar

Câu trả lời nhanh

Sử dụng biểu thức chính sau để xác thực đầu vào:

([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+

Địa chỉ phù hợp với regex này:

  • có một phần cục bộ (nghĩa là phần trước @ -sign) tuân thủ nghiêm ngặt với RFC 5321/5322,
  • có một phần tên miền (nghĩa là phần sau @ -sign) là tên Máy chủ lưu trữ có ít nhất hai nhãn, mỗi nhãn dài tối đa 63 ký tự.

Hạn chế thứ hai là một hạn chế đối với RFC 5321/5322.

Xây dựng câu trả lời

Sử dụng biểu thức chính quy nhận ra địa chỉ email có thể hữu ích trong các tình huống khác nhau: ví dụ: quét địa chỉ email trong tài liệu, để xác thực đầu vào của người dùng hoặc như một ràng buộc toàn vẹn trên kho lưu trữ dữ liệu.

Tuy nhiên, cần lưu ý rằng nếu bạn muốn tìm hiểu xem địa chỉ có thực sự đề cập đến hộp thư hiện có hay không, không có sự thay thế nào cho việc gửi tin nhắn đến địa chỉ. Nếu bạn chỉ muốn kiểm tra xem một địa chỉ có đúng ngữ pháp hay không thì bạn có thể sử dụng một biểu thức chính quy, nhưng lưu ý rằng ""@[] là một địa chỉ email chính xác về mặt ngữ pháp mà chắc chắn không đề cập đến hộp thư hiện có.

Cú pháp của địa chỉ email đã được xác định trong nhiều RFC , đáng chú ý nhất là RFC 822RFC 5322 . RFC 822 nên được coi là tiêu chuẩn "nguyên bản" và RFC 5322 là tiêu chuẩn mới nhất. Cú pháp được xác định trong RFC 822 là các tiêu chuẩn nhẹ nhàng nhất và tiếp theo đã hạn chế cú pháp ngày càng xa hơn, trong đó các hệ thống hoặc dịch vụ mới hơn sẽ nhận ra cú pháp lỗi thời, nhưng không bao giờ tạo ra nó.

Trong câu trả lời này, tôi sẽ lấy địa chỉ email của Google, có nghĩa là addr-spec như được định nghĩa trong RFC (tức là [email protected], nhưng không phải là "John Doe"<[email protected]>, cũng không phải là some-group:[email protected],[email protected];).

Có một vấn đề với việc dịch các cú pháp RFC thành regexes: các cú pháp không thường xuyên! Điều này là do chúng cho phép nhận xét tùy chọn trong các địa chỉ email có thể được lồng vô hạn, trong khi lồng vô hạn không thể được mô tả bằng một biểu thức thông thường. Để quét hoặc xác thực các địa chỉ có chứa các bình luận, bạn cần một trình phân tích cú pháp hoặc các biểu thức mạnh hơn. (Lưu ý rằng các ngôn ngữ như Perl có cấu trúc để mô tả ngữ pháp miễn phí theo ngữ cảnh theo cách giống như biểu thức chính quy.) Trong câu trả lời này, tôi sẽ bỏ qua các nhận xét và chỉ xem xét các biểu thức chính quy phù hợp.

RFC xác định cú pháp cho thông điệp email, không phải cho địa chỉ email như vậy. Địa chỉ có thể xuất hiện trong các trường tiêu đề khác nhau và đây là nơi chúng được xác định chủ yếu. Khi chúng xuất hiện trong các trường tiêu đề, địa chỉ có thể chứa (giữa các thẻ từ vựng) khoảng trắng, nhận xét và thậm chí ngắt dòng. Về mặt ngữ nghĩa, điều này không có ý nghĩa gì. Bằng cách xóa khoảng trắng này, v.v. khỏi một địa chỉ, bạn sẽ có được biểu diễn canonical tương đương về mặt ngữ nghĩa. Do đó, đại diện chính tắc của first. last (comment) @ [3.5.7.9][email protected][3.5.7.9].

Các cú pháp khác nhau nên được sử dụng cho các mục đích khác nhau. Nếu bạn muốn quét địa chỉ email trong tài liệu (có thể rất cũ), có thể nên sử dụng cú pháp như được định nghĩa trong RFC 822. Mặt khác, nếu bạn muốn xác thực đầu vào của người dùng, bạn có thể muốn sử dụng cú pháp như được định nghĩa trong RFC 5322, có lẽ chỉ chấp nhận các biểu diễn chính tắc. Bạn nên quyết định cú pháp nào áp dụng cho trường hợp cụ thể của bạn.

Tôi sử dụng các biểu thức chính quy "mở rộng" POSIX trong câu trả lời này, giả sử một bộ ký tự tương thích ASCII.

RFC 822

Tôi đến biểu hiện thường xuyên sau đây. Tôi mời mọi người dùng thử và phá vỡ nó. Nếu bạn tìm thấy bất kỳ dương tính giả hoặc phủ định sai, xin vui lòng gửi chúng trong một bình luận và tôi sẽ cố gắng sửa biểu thức càng sớm càng tốt.

([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*")(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*"))*@([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*])(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*]))*

Tôi tin rằng nó hoàn toàn phù hợp với RFC 822 bao gồm errata . Nó chỉ nhận ra địa chỉ email ở dạng chính tắc của họ. Đối với một regex nhận ra (gấp) khoảng trắng, xem đạo hàm bên dưới.

Đạo hàm cho thấy cách tôi đến biểu thức. Tôi liệt kê tất cả các quy tắc ngữ pháp có liên quan từ RFC chính xác khi chúng xuất hiện, theo sau là biểu thức chính quy tương ứng. Khi một lỗi sai đã được xuất bản, tôi đưa ra một biểu thức riêng cho quy tắc ngữ pháp đã sửa (được đánh dấu là "erratum") và sử dụng phiên bản cập nhật làm biểu thức con trong các biểu thức chính quy tiếp theo.

Như đã nêu trong đoạn 3.1.4. của RFC 822 khoảng trắng tuyến tính tùy chọn có thể được chèn giữa các mã thông báo từ vựng. Khi áp dụng, tôi đã mở rộng các biểu thức để phù hợp với quy tắc này và đánh dấu kết quả bằng "opt-lwsp".

CHAR        =  <any ASCII character>
            =~ .

CTL         =  <any ASCII control character and DEL>
            =~ [\x00-\x1F\x7F]

CR          =  <ASCII CR, carriage return>
            =~ \r

LF          =  <ASCII LF, linefeed>
            =~ \n

SPACE       =  <ASCII SP, space>
            =~  

HTAB        =  <ASCII HT, horizontal-tab>
            =~ \t

<">         =  <ASCII quote mark>
            =~ "

CRLF        =  CR LF
            =~ \r\n

LWSP-char   =  SPACE / HTAB
            =~ [ \t]

linear-white-space =  1*([CRLF] LWSP-char)
                   =~ ((\r\n)?[ \t])+

specials    =  "(" / ")" / "<" / ">" / "@" /  "," / ";" / ":" / "\" / <"> /  "." / "[" / "]"
            =~ [][()<>@,;:\\".]

quoted-pair =  "\" CHAR
            =~ \\.

qtext       =  <any CHAR excepting <">, "\" & CR, and including linear-white-space>
            =~ [^"\\\r]|((\r\n)?[ \t])+

dtext       =  <any CHAR excluding "[", "]", "\" & CR, & including linear-white-space>
            =~ [^][\\\r]|((\r\n)?[ \t])+

quoted-string  =  <"> *(qtext|quoted-pair) <">
               =~ "([^"\\\r]|((\r\n)?[ \t])|\\.)*"
(erratum)      =~ "(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*"

domain-literal =  "[" *(dtext|quoted-pair) "]"
               =~ \[([^][\\\r]|((\r\n)?[ \t])|\\.)*]
(erratum)      =~ \[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]

atom        =  1*<any CHAR except specials, SPACE and CTLs>
            =~ [^][()<>@,;:\\". \x00-\x1F\x7F]+

Word        =  atom / quoted-string
            =~ [^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*"

domain-ref  =  atom

sub-domain  =  domain-ref / domain-literal
            =~ [^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]

local-part  =  Word *("." Word)
            =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*")(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*"))*
(opt-lwsp)  =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*")(((\r\n)?[ \t])*\.((\r\n)?[ \t])*([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*"))*

domain      =  sub-domain *("." sub-domain)
            =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*])(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]))*
(opt-lwsp)  =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*])(((\r\n)?[ \t])*\.((\r\n)?[ \t])*([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]))*

addr-spec   =  local-part "@" domain
            =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*")(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*"))*@([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*])(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]))*
(opt-lwsp)  =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*")((\r\n)?[ \t])*(\.((\r\n)?[ \t])*([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*")((\r\n)?[ \t])*)*@((\r\n)?[ \t])*([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*])(((\r\n)?[ \t])*\.((\r\n)?[ \t])*([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]))*
(canonical) =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*")(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*"))*@([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*])(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*]))*

RFC 5322

Tôi đến biểu hiện thường xuyên sau đây. Tôi mời mọi người dùng thử và phá vỡ nó. Nếu bạn tìm thấy bất kỳ dương tính giả hoặc phủ định sai, xin vui lòng gửi chúng trong một bình luận và tôi sẽ cố gắng sửa biểu thức càng sớm càng tốt.

([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*])

Tôi tin rằng nó hoàn toàn phù hợp với RFC 5322 bao gồm errata . Nó chỉ nhận ra địa chỉ email ở dạng chính tắc của họ. Đối với một regex nhận ra (gấp) khoảng trắng, xem đạo hàm bên dưới.Đạo hàm cho thấy cách tôi đến biểu thức. Tôi liệt kê tất cả các quy tắc ngữ pháp có liên quan từ RFC chính xác khi chúng xuất hiện, theo sau là biểu thức chính quy tương ứng. Đối với các quy tắc bao gồm khoảng trắng (gấp) về mặt ngữ nghĩa, tôi đưa ra một biểu thức chính được đánh dấu "(chuẩn hóa)" không chấp nhận khoảng trắng này.

Tôi đã bỏ qua tất cả các quy tắc "quan sát" từ RFC. Điều này có nghĩa là các biểu thức chỉ phù hợp với các địa chỉ email tuân thủ nghiêm ngặt RFC 5322. Nếu bạn phải khớp các địa chỉ "cũ" (như ngữ pháp lỏng hơn bao gồm các quy tắc "obs-"), bạn có thể sử dụng một trong các biểu thức RFC 822 từ đoạn trước.

VCHAR = %x21-7E =~ [!-~] ALPHA = %x41-5A / %x61-7A =~ [A-Za-z] DIGIT = %x30-39 =~ [0-9] HTAB = %x09 =~ \t CR = %x0D =~ \r LF = %x0A =~ \n SP = %x20 =~ DQUOTE = %x22 =~ " CRLF = CR LF =~ \r\n WSP = SP / HTAB =~ [\t ] quoted-pair = "\" (VCHAR / WSP) =~ \\[\t -~] FWS = ([*WSP CRLF] 1*WSP) =~ ([\t ]*\r\n)?[\t ]+ ctext = %d33-39 / %d42-91 / %d93-126 =~ []!-'*-[^-~] ("comment" is left out in the regex) ccontent = ctext / quoted-pair / comment =~ []!-'*-[^-~]|(\\[\t -~]) (not regular) comment = "(" *([FWS] ccontent) [FWS] ")" (is equivalent to FWS when leaving out comments) CFWS = (1*([FWS] comment) [FWS]) / FWS =~ ([\t ]*\r\n)?[\t ]+ atext = ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~" =~ [-!#-'*+/-9=?A-Z^-~] dot-atom-text = 1*atext *("." 1*atext) =~ [-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)* dot-atom = [CFWS] dot-atom-text [CFWS] =~ (([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)? (normalized) =~ [-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)* qtext = %d33 / %d35-91 / %d93-126 =~ []!#-[^-~] qcontent = qtext / quoted-pair =~ []!#-[^-~]|(\\[\t -~]) (erratum) quoted-string = [CFWS] DQUOTE ((1*([FWS] qcontent) [FWS]) / FWS) DQUOTE [CFWS] =~ (([\t ]*\r\n)?[\t ]+)?"(((([\t ]*\r\n)?[\t ]+)?([]!#-[^-~]|(\\[\t -~])))+(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?)"(([\t ]*\r\n)?[\t ]+)? (normalized) =~ "([]!#-[^-~ \t]|(\\[\t -~]))+" dtext = %d33-90 / %d94-126 =~ [!-Z^-~] domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS] =~ (([\t ]*\r\n)?[\t ]+)?\[((([\t ]*\r\n)?[\t ]+)?[!-Z^-~])*(([\t ]*\r\n)?[\t ]+)?](([\t ]*\r\n)?[\t ]+)? (normalized) =~ \[[\t -Z^-~]*] local-part = dot-atom / quoted-string =~ (([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?"(((([\t ]*\r\n)?[\t ]+)?([]!#-[^-~]|(\\[\t -~])))+(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?)"(([\t ]*\r\n)?[\t ]+)? (normalized) =~ [-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+" domain = dot-atom / domain-literal =~ (([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?\[((([\t ]*\r\n)?[\t ]+)?[!-Z^-~])*(([\t ]*\r\n)?[\t ]+)?](([\t ]*\r\n)?[\t ]+)? (normalized) =~ [-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*] addr-spec = local-part "@" domain =~ ((([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?"(((([\t ]*\r\n)?[\t ]+)?([]!#-[^-~]|(\\[\t -~])))+(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?)"(([\t ]*\r\n)?[\t ]+)?)@((([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?\[((([\t ]*\r\n)?[\t ]+)?[!-Z^-~])*(([\t ]*\r\n)?[\t ]+)?](([\t ]*\r\n)?[\t ]+)?) (normalized) =~ ([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*])

Hạn chế hơn nữa.

SMTP (như được định nghĩa trong RFC 5321 ) tiếp tục hạn chế tập hợp các địa chỉ email hợp lệ (hoặc thực tế: tên hộp thư). Có vẻ hợp lý để áp đặt ngữ pháp chặt chẽ hơn này, để địa chỉ email phù hợp thực sự có thể được sử dụng để gửi email.

Về cơ bản, RFC 5321 chỉ để lại phần "cục bộ" (nghĩa là phần trước phần @ -ign), nhưng chặt chẽ hơn về phần miền (tức là phần sau phần @ -ign). Nó chỉ cho phép tên máy chủ thay cho các nguyên tử dấu chấm và địa chỉ bằng chữ thay cho tên miền.

Ngữ pháp được trình bày trong RFC 5321 quá nhẹ nhàng khi nói đến cả tên máy chủ và địa chỉ IP. Tôi đã tự do "sửa" các quy tắc trong câu hỏi, sử dụng dự thảo nàyRFC 1034 làm hướng dẫn. Đây là regex kết quả.

([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)*|\[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)]).

Lưu ý rằng tùy thuộc vào trường hợp sử dụng, bạn có thể không muốn cho phép "Địa chỉ chung theo nghĩa đen" trong biểu thức chính thức của mình. Cũng lưu ý rằng tôi đã sử dụng một cái nhìn tiêu cực (?!IPv6:) trong regex cuối cùng để ngăn phần "Địa chỉ chung-chữ" để khớp với các địa chỉ IPv6 không đúng định dạng. Một số bộ xử lý regex không hỗ trợ giao diện tiêu cực. Xóa chuỗi con |(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+ khỏi regex nếu bạn muốn lấy toàn bộ phần "Chung-địa chỉ-nghĩa đen".

Đây là đạo hàm:.

Let-Dig = ALPHA / DIGIT =~ [0-9A-Za-z] Ldh-str = *( ALPHA / DIGIT / "-" ) Let-Dig =~ [0-9A-Za-z-]*[0-9A-Za-z] (regex is updated to make sure sub-domains are max. 63 charactes long - RFC 1034 section 3.5) sub-domain = Let-Dig [Ldh-str] =~ [0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])? Domain = sub-domain *("." sub-domain) =~ [0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)* Snum = 1*3DIGIT =~ [0-9]{1,3} (suggested replacement for "Snum") ip4-octet = DIGIT / %x31-39 DIGIT / "1" 2DIGIT / "2" %x30-34 DIGIT / "25" %x30-35 =~ 25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9] IPv4-address-literal = Snum 3("." Snum) =~ [0-9]{1,3}(\.[0-9]{1,3}){3} (suggested replacement for "IPv4-address-literal") ip4-address = ip4-octet 3("." ip4-octet) =~ (25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3} (suggested replacement for "IPv6-hex") ip6-h16 = "0" / ( (%x49-57 / %x65-70 /%x97-102) 0*3(%x48-57 / %x65-70 /%x97-102) ) =~ 0|[1-9A-Fa-f][0-9A-Fa-f]{0,3} (not from RFC) ls32 = ip6-h16 ":" ip6-h16 / ip4-address =~ (0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3} (suggested replacement of "IPv6-addr") ip6-address = 6(ip6-h16 ":") ls32 / "::" 5(ip6-h16 ":") ls32 / [ ip6-h16 ] "::" 4(ip6-h16 ":") ls32 / [ *1(ip6-h16 ":") ip6-h16 ] "::" 3(ip6-h16 ":") ls32 / [ *2(ip6-h16 ":") ip6-h16 ] "::" 2(ip6-h16 ":") ls32 / [ *3(ip6-h16 ":") ip6-h16 ] "::" ip6-h16 ":" ls32 / [ *4(ip6-h16 ":") ip6-h16 ] "::" ls32 / [ *5(ip6-h16 ":") ip6-h16 ] "::" ip6-h16 / [ *6(ip6-h16 ":") ip6-h16 ] "::" =~ (((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?:: IPv6-address-literal = "IPv6:" ip6-address =~ IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::) Standardized-tag = Ldh-str =~ [0-9A-Za-z-]*[0-9A-Za-z] dcontent = %d33-90 / %d94-126 =~ [!-Z^-~] General-address-literal = Standardized-tag ":" 1*dcontent =~ [0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+ address-literal = "[" ( IPv4-address-literal / IPv6-address-literal / General-address-literal ) "]" =~ \[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)] Mailbox = Local-part "@" ( Domain / address-literal ) =~ ([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)*|\[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)])

Trường hợp sử dụng phổ biến là xác thực nhập liệu của người dùng, ví dụ trên biểu mẫu html. Trong trường hợp đó, thường là hợp lý để loại trừ địa chỉ bằng chữ và yêu cầu ít nhất hai nhãn trong tên máy chủ. Lấy regex RFC 5321 cải tiến từ phần trước làm cơ sở, biểu thức kết quả sẽ là:

([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+

Tôi không khuyên bạn nên hạn chế phần địa phương hơn nữa, ví dụ: bằng cách loại trừ các chuỗi được trích dẫn, vì chúng tôi không biết loại tên hộp thư nào mà một số máy chủ cho phép (như "a..b"@example.net hoặc thậm chí "a b"@example.net).

Tôi cũng không khuyên bạn nên xác nhận rõ ràng đối với danh sách các tên miền cấp cao nhất hoặc thậm chí áp đặt các ràng buộc về độ dài (hãy nhớ cách ".museum" bị vô hiệu hóa [a-z]{2,4}), nhưng nếu bạn phải:.

([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?\.)*(net|org|com|info|etc ...)

Đảm bảo cập nhật biểu thức chính quy của bạn nếu bạn quyết định đi theo con đường xác thực tên miền cấp cao rõ ràng.

Cân nhắc thêm.

Khi chỉ chấp nhận tên Máy chủ trong phần tên miền (sau @ -sign), các biểu thức trên chỉ chấp nhận các nhãn có tối đa 63 ký tự, nếu cần. Tuy nhiên, họ không thực thi thực tế là toàn bộ tên Máy chủ phải dài tối đa 253 ký tự (bao gồm cả dấu chấm). Mặc dù hạn chế này được nói một cách nghiêm túc vẫn đều đặn, nhưng việc đưa ra một biểu thức kết hợp quy tắc này là không khả thi.

Một cân nhắc khác, đặc biệt là khi sử dụng các biểu thức chính để xác thực đầu vào, là phản hồi cho người dùng. Nếu người dùng nhập địa chỉ không chính xác, sẽ rất vui nếu cung cấp thêm một chút thông tin phản hồi so với "địa chỉ cú pháp không chính xác" đơn giản. Với regex "Vanilla", điều này là không thể.

Hai cân nhắc này có thể được giải quyết bằng cách phân tích địa chỉ. Trong một số trường hợp, ràng buộc độ dài thêm đối với tên Máy chủ có thể được xử lý bằng cách sử dụng biểu thức chính bổ sung để kiểm tra nó và khớp địa chỉ với cả hai biểu thức.

Không có biểu thức nào trong câu trả lời này được tối ưu hóa cho hiệu suất. Nếu hiệu suất là một vấn đề, bạn nên xem liệu (và làm thế nào) biểu thức bạn chọn có thể được tối ưu hóa hay không.

None of the regexes in this answer are optimized for performance. If performance is an issue, you should see if (and how) the regex of your choice can be optimized.

103
Rinke

Có rất nhiều ví dụ về điều này trên mạng (và tôi nghĩ thậm chí một ví dụ xác nhận đầy đủ RFC - nhưng nó dài hàng chục/hàng trăm dòng nếu bộ nhớ phục vụ). Mọi người có xu hướng được mang đi xác nhận loại điều này. Tại sao không kiểm tra nó có @ và ít nhất một. và đáp ứng một số chiều dài tối thiểu đơn giản. Việc nhập một email giả mạo và vẫn phù hợp với bất kỳ regex hợp lệ nào. Tôi đoán rằng dương tính giả tốt hơn âm tính giả.

72
Draemon

Regex này là từ thư viện Email :: Hợp lệ của Perl. Tôi tin rằng nó là chính xác nhất, nó phù hợp với tất cả 822. Và, nó dựa trên biểu thức thông thường trong cuốn sách O'Reilly:

Biểu thức chính quy được xây dựng bằng ví dụ của Jeffrey Friedl trong Nắm vững các biểu thức chính quy ( http://www.ora.com/catalog/regapi/ ).

$RFC822PAT = <<'EOF';
[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\
xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xf
f\n\015()]*)*\)[\040\t]*)*(?:(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\x
ff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015
"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\
xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80
-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*
)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\
\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\
x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x8
0-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n
\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x
80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^
\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040
\t]*)*)*@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([
^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\
\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\
x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-
\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()
]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\
x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\04
0\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\
n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\
015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?!
[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\
]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\
x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\01
5()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*|(?:[^(\040)<>@,;:".
\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]
)|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^
()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037]*(?:(?:\([^\\\x80-\xff\n\0
15()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][
^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)|"[^\\\x80-\xff\
n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^()<>@,;:".\\\[\]\
x80-\xff\000-\010\012-\037]*)*<[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?
:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-
\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:@[\040\t]*
(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015
()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()
]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\0
40)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\
[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\
xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*
)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80
-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x
80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t
]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\
\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])
*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x
80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80
-\xff\n\015()]*)*\)[\040\t]*)*)*(?:,[\040\t]*(?:\([^\\\x80-\xff\n\015(
)]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\
\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*@[\040\t
]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\0
15()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015
()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(
\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|
\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80
-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()
]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x
80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^
\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040
\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".
\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff
])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\
\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x
80-\xff\n\015()]*)*\)[\040\t]*)*)*)*:[\040\t]*(?:\([^\\\x80-\xff\n\015
()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\
\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)?(?:[^
(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-
\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\
n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|
\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))
[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff
\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\x
ff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(
?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\
000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\
xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\x
ff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)
*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*@[\040\t]*(?:\([^\\\x80-\x
ff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-
\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)
*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\
]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\]
)[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-
\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\x
ff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(
?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80
-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<
>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x8
0-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:
\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]
*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)
*\)[\040\t]*)*)*>)
EOF
63
Evan Carroll

Trong khi quyết định những nhân vật nào được cho phép, xin vui lòng nhớ những người bạn bị bỏ mặc và gạch nối của bạn. Tôi không kiểm soát được việc công ty tôi tạo địa chỉ email bằng tên của tôi từ hệ thống nhân sự. Điều đó bao gồm dấu nháy đơn trong họ của tôi. Tôi không thể cho bạn biết tôi đã bị chặn tương tác với một trang web bao nhiêu lần bởi thực tế là địa chỉ email của tôi là "không hợp lệ". 

62
DOK

Khi bạn viết bằng PHP Tôi khuyên bạn nên sử dụng xác thực tích hợp PHP cho email.

filter_var($value, FILTER_VALIDATE_EMAIL)

Nếu bạn đang chạy phiên bản php thấp hơn 5.3.6, vui lòng lưu ý vấn đề này: https://bugs.php.net/orms.php?id=53091

Nếu bạn muốn biết thêm thông tin về cách xác thực buid-in này hoạt động, hãy xem tại đây: Bộ lọc của PHP_var FILTER_VALIDATE_EMAIL có thực sự hoạt động không?

46
SimonSimCity

Cal Henderson (Flickr) đã viết một bài báo có tên Phân tích địa chỉ email trong PHP và chỉ ra cách thực hiện phân tích địa chỉ email tuân thủ RFC (2) 822 phù hợp. Bạn cũng có thể lấy mã nguồn trong php , python và Ruby đó là cc được cấp phép .

43
adnam

Tôi không bao giờ bận tâm đến việc tạo ra với biểu thức chính quy của riêng mình, bởi vì rất có thể là người khác đã đưa ra một phiên bản tốt hơn. Tôi luôn luôn sử dụng regexlib để tìm một cái theo ý thích của tôi.

42
Kon

Không có cái nào thực sự có thể sử dụng được.
Tôi thảo luận về một số vấn đề trong câu trả lời của tôi Có thư viện php để xác thực địa chỉ email không? , nó cũng được thảo luận trong Nhận dạng chính xác địa chỉ email có khó không?

Nói tóm lại, đừng mong đợi một regex duy nhất, có thể sử dụng để thực hiện một công việc phù hợp. Và regex tốt nhất sẽ xác thực cú pháp, không phải tính hợp lệ của e-mail ([email protected] là chính xác nhưng nó có thể sẽ bị trả lại ...).

37
PhiLho

Một biểu thức chính quy đơn giản mà ít nhất sẽ không từ chối bất kỳ địa chỉ email hợp lệ nào sẽ là kiểm tra một cái gì đó, theo sau là dấu @ và sau đó là một khoảng thời gian và ít nhất là 2 lần. Nó sẽ không từ chối bất cứ điều gì, nhưng sau khi xem xét thông số kỹ thuật tôi không thể tìm thấy bất kỳ email nào hợp lệ và bị từ chối.

email = ~ /[email protected][^@]+\.[^@]{2,}$/

34
spig

Bạn có thể sử dụng cái được sử dụng bởi plugin Xác thực jQuery:

/^((([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])))\.?$/i
30
chaos

Để đánh giá toàn diện nhất về biểu thức chính quy tốt nhất để xác thực địa chỉ email, vui lòng xem liên kết này; " So sánh địa chỉ email xác thực biểu thức chính quy "

Đây là biểu thức hàng đầu hiện tại cho mục đích tham khảo:

/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~][email protected]((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i
25
Eric Schoonover

Không đề cập đến việc các tên miền không phải là tiếng Latin (tiếng Trung, tiếng Ả Rập, tiếng Hy Lạp, tiếng Do Thái, tiếng Cyrillic, v.v.) sẽ được cho phép trong tương lai gần . Mọi người phải thay đổi regex email được sử dụng, bởi vì những ký tự đó chắc chắn không được bao phủ bởi [a-z]/i hay \w. Tất cả họ sẽ thất bại.

Rốt cuộc, cách tốt nhất để xác thực địa chỉ email vẫn là thực sự gửi một email đến địa chỉ được đề cập để xác thực địa chỉ. Nếu địa chỉ email là một phần của xác thực người dùng (đăng ký/đăng nhập/vv), thì bạn hoàn toàn có thể kết hợp nó với hệ thống kích hoạt người dùng. I E. gửi email có liên kết với khóa kích hoạt duy nhất đến địa chỉ email được chỉ định và chỉ cho phép đăng nhập khi người dùng đã kích hoạt tài khoản mới tạo bằng liên kết trong email.

Nếu mục đích của regex chỉ là nhanh chóng thông báo cho người dùng trong giao diện người dùng rằng địa chỉ email được chỉ định không giống với định dạng đúng, tốt nhất vẫn là kiểm tra xem về cơ bản có khớp với regex sau không:

^([^[email protected]]+)(\.[^[email protected]]+)*@([^[email protected]]+\.)+([^[email protected]]+)$

Đơn giản như vậy. Tại sao bạn lại quan tâm đến các ký tự được sử dụng trong tên và miền? Khách hàng có trách nhiệm nhập địa chỉ email hợp lệ, không phải của máy chủ. Ngay cả khi khách hàng nhập địa chỉ email hợp lệ cú pháp như [email protected], điều này không đảm bảo rằng đó là địa chỉ email hợp pháp. Không ai regex có thể bao gồm điều đó.

23
BalusC

Thông số HTML5 gợi ý một biểu thức chính đơn giản để xác thực địa chỉ email:

/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-][email protected][a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/

Điều này cố ý không tuân thủ RFC 5322 .

Lưu ý: Yêu cầu này là vi phạm cố ý của RFC 5322 , xác định cú pháp cho các địa chỉ email đồng thời quá nghiêm ngặt (trước ký tự @), quá mơ hồ (sau @ ký tự) và quá lỏng lẻo (cho phép nhận xét, ký tự khoảng trắng và chuỗi trích dẫn trong cách cư xử không quen thuộc với hầu hết người dùng) được sử dụng thực tế tại đây.

Tổng chiều dài cũng có thể được giới hạn ở 254 ký tự, mỗi RFC 3696 errata 1690 .

18
Luna

Đối với một minh chứng sống động, con quái vật sau đây khá tốt nhưng vẫn không nhận ra chính xác tất cả các địa chỉ email hợp lệ về mặt cú pháp: nó nhận ra các bình luận lồng nhau sâu tới bốn cấp.

Đây là một công việc cho một trình phân tích cú pháp, nhưng ngay cả khi một địa chỉ có giá trị cú pháp, nó vẫn có thể không được cung cấp. Đôi khi bạn phải dùng đến phương pháp Hillbilly của "Hey, y'all, xem ee-us!"

// derivative of work with the following copyright and license:
// Copyright (c) 2004 Casey West.  All rights reserved.
// This module is free software; you can redistribute it and/or
// modify it under the same terms as Perl itself.

// see http://search.cpan.org/~cwest/Email-Address-1.80/

private static string gibberish = @"
(?-xism:(?:(?-xism:(?-xism:(?-xism:(?-xism:(?-xism:(?-xism:\
s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^
\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))
|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+
|\s+)*[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+(?-xism:(?-xism:\
s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^
\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))
|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+
|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(
?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?
:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x
0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*<DQ>(?-xism:(?-xism:[
^\\<DQ>])|(?-xism:\\(?-xism:[^\x0A\x0D])))+<DQ>(?-xism:(?-xi
sm:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xis
m:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\
]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\
s*)+|\s+)*))+)?(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?
-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:
\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[
^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*<(?-xism:(?-xi
sm:(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^(
)\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(
?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))
|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()<
>\[\]:;@\,.<DQ>\s]+(?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]
+)*)(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))
|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:
(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s
*\)\s*))+)*\s*\)\s*)+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?
:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x
0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xi
sm:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*
<DQ>(?-xism:(?-xism:[^\\<DQ>])|(?-xism:\\(?-xism:[^\x0A\x0D]
)))+<DQ>(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\
]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-x
ism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+
)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*))\@(?-xism:(?-xism:(?-xism:(
?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?
-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^
()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s
*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+(
?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+)*)(?-xism:(?-xism:
\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[
^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+)
)|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)
+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:
(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((
?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\
x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*\[(?:\s*(?-xism:(?-x
ism:[^\[\]\\])|(?-xism:\\(?-xism:[^\x0A\x0D])))+)*\s*\](?-xi
sm:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:
\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(
?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+
)*\s*\)\s*)+|\s+)*)))>(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-
xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\
s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^
\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*))|(?-xism:(?-x
ism:(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^
()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*
(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D])
)|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()
<>\[\]:;@\,.<DQ>\s]+(?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s
]+)*)(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+)
)|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism
:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\
s*\)\s*))+)*\s*\)\s*)+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((
?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\
x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-x
ism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)
*<DQ>(?-xism:(?-xism:[^\\<DQ>])|(?-xism:\\(?-xism:[^\x0A\x0D
])))+<DQ>(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\
\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-
xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)
+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*))\@(?-xism:(?-xism:(?-xism:
(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(
?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[
^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\
s*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+
(?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+)*)(?-xism:(?-xism
:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:
[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+
))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*
)+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism
:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\(
(?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A
\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*\[(?:\s*(?-xism:(?-
xism:[^\[\]\\])|(?-xism:\\(?-xism:[^\x0A\x0D])))+)*\s*\](?-x
ism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism
:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:
(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))
+)*\s*\)\s*)+|\s+)*))))(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?
>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:
\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0
D]))|)+)*\s*\)\s*))+)*\s*\)\s*)*)"
  .Replace("<DQ>", "\"")
  .Replace("\t", "")
  .Replace(" ", "")
  .Replace("\r", "")
  .Replace("\n", "");

private static Regex mailbox =
  new Regex(gibberish, RegexOptions.ExplicitCapture); 
15
Greg Bacon

Đây là PHP tôi sử dụng. Tôi đã chọn giải pháp này theo tinh thần "dương tính giả tốt hơn âm tính giả" như tuyên bố của một người bình luận khác ở đây VÀ liên quan đến việc giữ thời gian phản hồi của bạn và tải xuống máy chủ ... thực sự không cần phải lãng phí tài nguyên máy chủ một biểu thức chính quy khi điều này sẽ loại bỏ lỗi người dùng đơn giản nhất. Bạn luôn có thể theo dõi điều này bằng cách gửi email kiểm tra nếu bạn muốn.

function validateEmail($email) {
  return (bool) stripos($email,'@');
}
12
Mac

Theo tiêu chuẩn chính thức RFC 2822 regex email hợp lệ là 

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

nếu bạn muốn sử dụng nó trong Java thì thực sự rất dễ dàng

import Java.util.regex.*;

class regexSample 
{
   public static void main(String args[]) 
   {
      //Input the string for validation
      String email = "[email protected]";

      //Set the email pattern string
      Pattern p = Pattern.compile(" (?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"
              +"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")"
                     + "@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\]");

      //Match the given string with the pattern
      Matcher m = p.matcher(email);

      //check whether match is found 
      boolean matchFound = m.matches();

      if (matchFound)
        System.out.println("Valid Email Id.");
      else
        System.out.println("Invalid Email Id.");
   }
}
11
AZ_

Tiêu chuẩn RFC 5322:

Cho phép tên miền cục bộ phần nguyên tử, phần cục bộ chuỗi, phần tử lỗi thời (phần tử dấu chấm hỗn hợp và phần trích dẫn) phần tên miền, tên miền tên miền, (địa chỉ IPv6 được ánh xạ IPv4) và (lồng nhau) CFWS.

'/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD'

Tiêu chuẩn RFC 5321:

Cho phép tên miền cục bộ phần tử, phần địa phương, chuỗi tên miền và tên miền (IPv4, IPv6 và địa chỉ IPv6 được ánh xạ IPv4) tên miền.

'/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!"?(?>\\\[ -~]|[^"]){65,}"[email protected])(?>([!#-\'*+\/-9=?^-~-]+)(?>\.(?1))*|"(?>[ !#-\[\]-~]|\\\[ -~])*")@(?!.*[^.]{64,})(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?2)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?3)){7}|(?!(?:.*[a-f0-9][:\]]){8,})((?3)(?>:(?3)){0,6})?::(?4)?))|(?>(?>IPv6:(?>(?3)(?>:(?3)){5}:|(?!(?:.*[a-f0-9]:){6,})(?5)?::(?>((?3)(?>:(?3)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?6)){3}))\])$/iD'

Căn bản:

Cho phép tên miền tên miền cục bộ và tên miền (yêu cầu ít nhất hai nhãn tên miền với TLD giới hạn ở 2-6 ký tự chữ cái).

"/^(?!.{255,})(?!.{65,}@)([!#-'*+\/-9=?^-~-]+)(?>\.(?1))*@(?!.*[^.]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?\.){1,126}[a-z]{2,6}$/iD"
11
MichaelRushton
public bool ValidateEmail(string sEmail)
{
    if (sEmail == null)
    {
        return false;
    }

    int nFirstAT = sEmail.IndexOf('@');
    int nLastAT = sEmail.LastIndexOf('@');

    if ((nFirstAT > 0) && (nLastAT == nFirstAT) && (nFirstAT < (sEmail.Length - 1)))
    {
        return (Regex.IsMatch(sEmail, @"^[a-z|0-9|A-Z]*([_][a-z|0-9|A-Z]+)*([.][a-z|0-9|A-Z]+)*([.][a-z|0-9|A-Z]+)*(([_][a-z|0-9|A-Z]+)*)[email protected][a-z][a-z|0-9|A-Z]*\.([a-z][a-z|0-9|A-Z]*(\.[a-z][a-z|0-9|A-Z]*)?)$"));
    }
    else
    {
        return false;
    }
}
8
Murthy Jeedigunta

Kỳ lạ là bạn "không thể" cho phép TLD 4 ký tự. Bạn đang cấm mọi người từ .info.name và dừng giới hạn độ dài .travel.museum, nhưng vâng, chúng ít phổ biến hơn 2 TLD 3 ký tự TLD.

Bạn cũng nên cho phép bảng chữ cái viết hoa. Hệ thống email sẽ bình thường hóa phần cục bộ và phần tên miền.

Đối với regex của bạn về phần tên miền, tên miền không thể bắt đầu bằng '-' và không thể kết thúc bằng '-'. Dash chỉ có thể ở giữa.

Nếu bạn đã sử dụng thư viện PEAR, hãy kiểm tra chức năng thư của họ (quên tên/thư viện chính xác). Bạn có thể xác thực địa chỉ email bằng cách gọi một chức năng và nó xác nhận địa chỉ email theo định nghĩa trong RFC822.

8
Joseph Yee

Nếu bạn ổn với việc chấp nhận các giá trị trống (không phải là email không hợp lệ) và đang chạy PHP 5.2+, tôi sẽ đề xuất:

static public function checkEmail($email, $ignore_empty = false) {
        if($ignore_empty && (is_null($email) || $email == ''))
                return true;
        return filter_var($email, FILTER_VALIDATE_EMAIL);
    }
7
Prasad

Tôi đã sử dụng phiên bản regex này của bạn trong một thời gian và nó không để lại cho tôi quá nhiều bất ngờ. Tôi chưa bao giờ gặp phải dấu nháy đơn trong email vì vậy nó không xác thực rằng. Nó xác nhận Jean+Franç[email protected]试@例子.测试.مثال.آزمایشی nhưng không lạm dụng những ký tự không chữ và số [email protected]

(?!^[.+&'_-]*@.*$)(^[_\w\d+&'-]+(\.[_\w\d+&'-]*)*@[\w\d-]+(\.[\w\d-]+)*\.(([\d]{1,3})|([\w]{2,}))$)

Nó không hỗ trợ địa chỉ IP [email protected] nhưng tôi chưa tinh chỉnh đủ để xử lý các dải IP không có thật, chẳng hạn như 999.999.999.1.

Nó cũng hỗ trợ tất cả các TLD trên 3 ký tự dừng [email protected] mà tôi nghĩ rằng bản gốc đã bỏ qua. Tôi đã bị đánh bại, hiện có quá nhiều tlds trên 3 ký tự.

Tôi biết acrosman đã từ bỏ regex của mình nhưng hương vị này vẫn tiếp tục.

7
TombMedia

Tôi biết câu hỏi này là về RegEx, nhưng đoán rằng 90% tất cả các nhà phát triển đang đọc các giải pháp này đang cố xác thực địa chỉ E-Mail dưới dạng HTML được hiển thị trong trình duyệt. 

Nếu đây là trường hợp, tôi khuyên bạn nên kiểm tra phần tử biểu mẫu HTML5 <input type="email"> mới:

HTML5:

 <input type="email" required />

CSS3:

 input:required {
      background-color: rgba(255,0,0,0.2);
 }

 input:focus:invalid { 
     box-shadow: 0 0 1em red;
     border-color: red;
 }

 input:focus:valid { 
     box-shadow: 0 0 1em green;
     border-color: green;
 }

http://jsfiddle.net/mYRe7/1

Điều này có một vài lợi thế:

  1. Xác thực tự động, không cần giải pháp tùy chỉnh: đơn giản và dễ thực hiện
  2. Không có JavaScript, không có vấn đề gì nếu JS đã bị vô hiệu hóa
  3. Không có máy chủ phải tính toán bất cứ điều gì cho điều đó
  4. Người dùng có phản hồi ngay lập tức
  5. Trình duyệt cũ sẽ tự động chuyển sang loại "văn bản" đầu vào
  6. Các trình duyệt di động có thể hiển thị một bàn phím chuyên dụng (@ -Pal)
  7. Phản hồi xác thực mẫu rất dễ dàng với CSS3 

Nhược điểm rõ ràng có thể thiếu xác nhận cho các trình duyệt cũ, nhưng điều đó sẽ thay đổi theo thời gian. Tôi thích điều này hơn bất kỳ kiệt tác RegEx điên rồ nào.

cũng thấy:

6
auco

Tôi luôn sử dụng biểu thức chính quy dưới đây để xác thực địa chỉ email. Đây là regex tốt nhất tôi từng thấy để xác nhận địa chỉ email.

"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z";

Biểu thức chính quy này tôi luôn sử dụng trong Mã Asp.NET của mình và tôi khá hài lòng với nó.

sử dụng tài liệu tham khảo hội này

using System.Text.RegularExpressions;

và thử đoạn mã sau, vì nó đơn giản và thực hiện công việc cho bạn.

private bool IsValidEmail(string email) {
    bool isValid = false;
    const string pattern = @"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z";

    isValid = email != "" && Regex.IsMatch(email, pattern);

    // an alternative of the above line is also given and commented
    //
    //if (email == "") {
    //    isValid = false;
    //} else {
    //    // address provided so use the IsMatch Method
    //    // of the Regular Expression object
    //    isValid = Regex.IsMatch(email, pattern);
    //}
    return isValid;
}

chức năng này xác nhận chuỗi email. Nếu chuỗi email là null, nó sẽ trả về false, nếu chuỗi email không đúng định dạng, nó sẽ trả về false. Nó chỉ trả về true nếu định dạng của email là hợp lệ.

6
Suhaib Janjua

Gần như mọi RegEx mà tôi đã thấy - bao gồm một số được Microsoft sử dụng sẽ không cho phép hợp lệ email sau đây được thông qua: [email protected]

Chỉ cần có một khách hàng thực sự với một địa chỉ email ở định dạng này, người không thể đặt hàng.

Đây là những gì tôi giải quyết: 

  • Một Regex tối thiểu sẽ không có tiêu cực sai. Hoặc sử dụng hàm tạo MailAddress với một số kiểm tra bổ sung (xem bên dưới):
  • Kiểm tra các lỗi chính tả phổ biến .cmo hoặc .gmial.com và yêu cầu xác nhận Are you sure this is your correct email address. It looks like there may be a mistake. Cho phép người dùng chấp nhận những gì họ đã nhập nếu họ chắc chắn.
  • Xử lý bị trả lại khi email thực sự được gửi và xác minh chúng theo cách thủ công để kiểm tra các lỗi rõ ràng.

        try
        {
            var email = new MailAddress(str);

            if (email.Host.EndsWith(".cmo"))
            {
                return EmailValidation.PossibleTypo;
            }

            if (!email.Host.EndsWith(".") && email.Host.Contains("."))
            {
                return EmailValidation.OK;
            }
        }
        catch
        {
            return EmailValidation.Invalid;
        }
5
Simon_Weaver

đây là một trong những regex cho email

^((([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])))\.?$
5
Nazmul Hasan

Tôi không tin rằng tuyên bố của bortzmeyer, ở trên, rằng "Ngữ pháp (được quy định trong RFC 5322) quá phức tạp cho điều đó" (được xử lý bằng một biểu thức thông thường).

Đây là ngữ pháp: (từ http://tools.ietf.org/html/rfc5322#section-3.4.1 )

addr-spec       =   local-part "@" domain
local-part      =   dot-atom / quoted-string / obs-local-part
domain          =   dot-atom / domain-literal / obs-domain
domain-literal  =   [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
dtext           =   %d33-90 /          ; Printable US-ASCII
                    %d94-126 /         ;  characters not including
                    obs-dtext          ;  "[", "]", or "\"

Giả sử rằng nguyên tử chấm, chuỗi trích dẫn, phần obs-local, obs-domain là ngôn ngữ thông thường, đây là một ngữ pháp rất đơn giản. Chỉ cần thay thế phần cục bộ và tên miền trong sản xuất addr-spec bằng các sản phẩm tương ứng của chúng và bạn có ngôn ngữ thông thường, có thể dịch trực tiếp thành biểu thức chính quy.

5
Dimitris Andreou

Tôi sử dụng xác nhận nhiều bước. Vì không có cách nào hoàn hảo để xác thực địa chỉ email, nên không thể thực hiện một địa chỉ hoàn hảo, nhưng ít nhất bạn có thể thông báo cho người dùng rằng anh ấy/cô ấy đang làm gì đó sai - đây là cách tiếp cận của tôi

1) Trước tiên tôi xác nhận bằng regex rất cơ bản chỉ kiểm tra xem email có chứa chính xác một dấu @ không và nó không trống trước hoặc sau dấu đó. ví dụ. /^[^@\s][email protected][^@\s]+$/

2a) nếu trình xác nhận đầu tiên không vượt qua (và đối với hầu hết các địa chỉ thì mặc dù nó không hoàn hảo), sau đó cảnh báo người dùng email không hợp lệ và không cho phép anh ta/cô ta tiếp tục với đầu vào

2b) nếu nó vượt qua, sau đó xác nhận chống lại regex nghiêm ngặt hơn - thứ gì đó có thể không cho phép các email hợp lệ. Nếu nó không vượt qua, người dùng sẽ được cảnh báo về lỗi có thể xảy ra nhưng được phép tiếp tục. Không giống như bước (1) trong đó người dùng không được phép tiếp tục vì đó là một lỗi rõ ràng.

Vì vậy, nói cách khác, xác nhận tự do đầu tiên chỉ là loại bỏ các lỗi rõ ràng và nó được coi là "lỗi". Mọi người gõ một địa chỉ trống, địa chỉ không có dấu @ và như vậy. Điều này nên được coi là lỗi. Cái thứ hai nghiêm ngặt hơn nhưng được coi là "cảnh báo" và người dùng được phép tiếp tục với đầu vào nhưng cảnh báo ít nhất là kiểm tra xem anh ấy/cô ấy đã nhập một mục hợp lệ. Chìa khóa ở đây là trong cách tiếp cận lỗi/cảnh báo - lỗi là thứ không thể dưới 99,99% là email hợp lệ.

Của couse, bạn có thể điều chỉnh những gì làm cho một regex đầu tiên tự do hơn và thứ hai nghiêm ngặt hơn.

Tùy thuộc vào những gì bạn cần, phương pháp trên có thể phù hợp với bạn.

5
Coder12345

NHƯ theo hiểu biết của tôi, hầu hết các khả năng sẽ bao gồm bởi ..

/^([a-z0-9_-]+)(@[a-z0-9-]+)(\.[a-z]+|\.[a-z]+\.[a-z]+)?$/is
4
Mohit Gupta

Đối với tôi cách đúng để kiểm tra email là:

  1. Kiểm tra biểu tượng @ tồn tại và trước và sau nó có một số biểu tượng không @: /^[^@][email protected][^@]+$/
  2. Cố gắng gửi email đến địa chỉ này với một số "mã kích hoạt".
  3. Khi người dùng "kích hoạt" địa chỉ email của mình, chúng ta sẽ thấy tất cả đều đúng.

Tất nhiên, bạn có thể hiển thị một số cảnh báo hoặc chú giải công cụ ở mặt trước khi người dùng nhập email "lạ" để giúp anh ta tránh các lỗi phổ biến, như không có dấu chấm trong phần tên miền hoặc dấu cách trong tên mà không cần trích dẫn, v.v. Nhưng bạn phải chấp nhận địa chỉ "hello @ world" nếu người dùng thực sự muốn nó.

Ngoài ra, bạn phải nhớ rằng tiêu chuẩn địa chỉ email đã và có thể phát triển, vì vậy bạn không thể chỉ cần nhập một số regrec "hợp lệ tiêu chuẩn" một lần và mãi mãi. Và bạn phải nhớ rằng một số máy chủ internet cụ thể có thể thất bại một số chi tiết về tiêu chuẩn chung và trên thực tế hoạt động với "tiêu chuẩn được sửa đổi".

Vì vậy, chỉ cần kiểm tra @, gợi ý người dùng ở lối vào và gửi email xác minh theo địa chỉ đã cho.

4
FlameStorm

Tôi vẫn đang sử dụng:

^[A-Za-z0-9._+\-\'][email protected][A-Za-z0-9.\-]+\.[A-Za-z]{2,}$

Nhưng với IPv6 và Unicode sắp ra mắt, có lẽ:

^\w[^@\s]*@[^@\s]{2,}$

là tốt nhất. Gmail đã cho phép các dấu chấm liên tiếp, nhưng Microsoft Exchange Server 2007 từ chối chúng.

4
Cees Timmerman

Tôi không tìm thấy bất kỳ giao dịch với tên miền cấp cao nhất nhưng nó nên được xem xét.

Vì vậy, đối với tôi sau khi làm việc-

[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}AAA|AARP|ABB|ABBOTT|ABOGADO|AC|ACADEMY|ACCENTURE|ACCOUNTANT|ACCOUNTANTS|ACO|ACTIVE|ACTOR|AD|ADAC|ADS|ADULT|AE|AEG|AERO|AF|AFL|AG|AGENCY|AI|AIG|AIRFORCE|AIRTEL|AL|ALIBABA|ALIPAY|ALLFINANZ|ALSACE|AM|AMICA|AMSTERDAM|ANALYTICS|Android|AO|APARTMENTS|APP|Apple|AQ|AQUARELLE|AR|ARAMCO|ARCHI|ARMY|ARPA|ARTE|AS|ASIA|ASSOCIATES|AT|ATTORNEY|AU|AUCTION|AUDI|AUDIO|AUTHOR|AUTO|AUTOS|AW|AX|AXA|AZ|Azure|BA|BAIDU|BAND|BANK|BAR|BARCELONA|BARCLAYCARD|BARCLAYS|BARGAINS|BAUHAUS|BAYERN|BB|BBC|BBVA|BCN|BD|BE|BEATS|BEER|BENTLEY|BERLIN|BEST|BET|BF|BG|BH|BHARTI|BI|BIBLE|BID|BIKE|BING|BINGO|BIO|BIZ|BJ|BLACK|BLACKFRIDAY|BLOOMBERG|BLUE|BM|BMS|BMW|BN|BNL|BNPPARIBAS|BO|BOATS|BOEHRINGER|BOM|BOND|BOO|BOOK|BOOTS|BOSCH|BOSTIK|BOT|BOUTIQUE|BR|BRADESCO|BRIDGESTONE|BROADWAY|BROKER|BROTHER|BRUSSELS|BS|BT|BUDAPEST|BUGATTI|BUILD|BUILDERS|BUSINESS|BUY|BUZZ|BV|BW|BY|BZ|BZH|CA|CAB|CAFE|CAL|CALL|CAMERA|CAMP|CANCERRESEARCH|Canon|CAPETOWN|CAPITAL|CAR|CARAVAN|CARDS|CARE|CAREER|CAREERS|CARS|CARTIER|CASA|CASH|CASINO|CAT|CATERING|CBA|CBN|CC|CD|CEB|CENTER|CEO|CERN|CF|CFA|CFD|CG|CH|CHANEL|CHANNEL|CHAT|CHEAP|CHLOE|CHRISTMAS|CHROME|CHURCH|CI|CIPRIANI|CIRCLE|Cisco|CITIC|CITY|CITYEATS|CK|CL|CLAIMS|CLEANING|CLICK|CLINIC|CLINIQUE|CLOTHING|CLOUD|CLUB|CLUBMED|CM|CN|CO|COACH|CODES|COFFEE|COLLEGE|COLOGNE|COM|COMMBANK|COMMUNITY|COMPANY|COMPARE|COMPUTER|COMSEC|CONDOS|CONSTRUCTION|CONSULTING|CONTACT|CONTRACTORS|COOKING|COOL|COOP|CORSICA|COUNTRY|COUPONS|COURSES|CR|CREDIT|CREDITCARD|CREDITUNION|CRICKET|CROWN|CRS|CRUISES|CSC|CU|CUISINELLA|CV|CW|CX|CY|CYMRU|CYOU|CZ|DABUR|DAD|DANCE|DATE|DATING|DATSUN|DAY|DCLK|DE|DEALER|DEALS|DEGREE|DELIVERY|Dell|DELTA|DEMOCRAT|DENTAL|DENTIST|DESI|DESIGN|DEV|DIAMONDS|DIET|DIGITAL|DIRECT|DIRECTORY|DISCOUNT|DJ|DK|DM|DNP|DO|DOCS|DOG|DOHA|DOMAINS|DOOSAN|DOWNLOAD|DRIVE|DUBAI|DURBAN|DVAG|DZ|EARTH|EAT|EC|EDEKA|EDU|EDUCATION|EE|EG|EMAIL|EMERCK|ENERGY|ENGINEER|ENGINEERING|ENTERPRISES|EPSON|EQUIPMENT|ER|ERNI|ES|ESQ|ESTATE|ET|EU|EUROVISION|EUS|EVENTS|EVERBANK|EXCHANGE|EXPERT|EXPOSED|EXPRESS|FAGE|FAIL|FAIRWINDS|FAITH|FAMILY|FAN|FANS|FARM|FASHION|FAST|FEEDBACK|FERRERO|FI|FILM|FINAL|FINANCE|FINANCIAL|FIRESTONE|FIRMDALE|FISH|FISHING|FIT|FITNESS|FJ|FK|FLIGHTS|FLORIST|FLOWERS|FLSMIDTH|FLY|FM|FO|FOO|FOOTBALL|FORD|FOREX|FORSALE|FORUM|FOUNDATION|FOX|FR|FRESENIUS|FRL|FROGANS|FUND|FURNITURE|FUTBOL|FYI|GA|GAL|GALLERY|GAME|GARDEN|GB|GBIZ|Gd|GDN|GE|GEA|GENT|GENTING|GF|GG|GGEE|GH|GI|GIFT|GIFTS|GIVES|GIVING|GL|GLASS|GLE|GLOBAL|GLOBO|GM|GMAIL|GMO|GMX|GN|GOLD|GOLDPOINT|GOLF|GOO|GOOG|GOOGLE|GOP|GOT|GOV|GP|GQ|GR|GRAINGER|GRAPHICS|GRATIS|GREEN|GRIPE|GROUP|GS|GT|GU|GUCCI|GUGE|GUIDE|GUITARS|GURU|GW|GY|HAMBURG|HANGOUT|HAUS|HEALTH|HEALTHCARE|HELP|HELSINKI|HERE|HERMES|HIPHOP|HITACHI|HIV|HK|HM|HN|HOCKEY|HOLDINGS|HOLIDAY|HOMEDEPOT|HOMES|HONDA|HORSE|Host|HOSTING|HOTELES|HOTMAIL|HOUSE|HOW|HR|HSBC|HT|HU|HYUNDAI|IBM|ICBC|ICE|ICU|ID|IE|IFM|IINET|IL|IM|IMMO|IMMOBILIEN|IN|INDUSTRIES|INFINITI|INFO|ING|INK|INSTITUTE|INSURANCE|INSURE|INT|INTERNATIONAL|INVESTMENTS|IO|IPIRANGA|IQ|IR|IRISH|IS|ISELECT|IST|ISTANBUL|IT|ITAU|IWC|JAGUAR|Java|JCB|JE|JETZT|JEWELRY|JLC|JLL|JM|JMP|JO|JOBS|JOBURG|JOT|JOY|JP|JPRS|JUEGOS|KAUFEN|KDDI|KE|KFH|KG|KH|KI|KIA|KIM|KINDER|KITCHEN|KIWI|KM|KN|KOELN|KOMATSU|KP|KPN|KR|KRD|KRED|KW|KY|KYOTO|KZ|LA|LACAIXA|LAMBORGHINI|LAMER|LANCASTER|LAND|LANDROVER|LANXESS|LASALLE|LAT|LATROBE|LAW|LAWYER|LB|LC|LDS|LEASE|LECLERC|LEGAL|LEXUS|LGBT|LI|LIAISON|LIDL|LIFE|LIFEINSURANCE|LIFESTYLE|LIGHTING|LIKE|LIMITED|LIMO|LINCOLN|LINDE|LINK|LIVE|LIVING|LIXIL|LK|LOAN|LOANS|LOL|LONDON|LOTTE|LOTTO|LOVE|LR|LS|LT|LTD|LTDA|LU|LUPIN|LUXE|LUXURY|LV|LY|MA|MADRID|MAIF|MAISON|MAKEUP|MAN|MANAGEMENT|MANGO|MARKET|MARKETING|MARKETS|MARRIOTT|MBA|MC|MD|ME|MED|MEDIA|MEET|MELBOURNE|MEME|MEMORIAL|MEN|MENU|MEO|MG|MH|MIAMI|Microsoft|MIL|MINI|MK|ML|MM|MMA|MN|MO|MOBI|MOBILY|MODA|MOE|MOI|MOM|MONASH|MONEY|MONTBLANC|MORMON|MORTGAGE|MOSCOW|MOTORCYCLES|MOV|MOVIE|MOVISTAR|MP|MQ|MR|MS|MT|MTN|MTPC|MTR|MU|MUSEUM|MUTUELLE|MV|MW|MX|MY|MZ|NA|NADEX|NAGOYA|NAME|NAVY|NC|NE|NEC|NET|NETBANK|NETWORK|NEUSTAR|NEW|NEWS|NEXUS|NF|NG|NGO|NHK|NI|NICO|NINJA|NISSAN|NL|NO|NOKIA|NORTON|NOWRUZ|NP|NR|NRA|NRW|NTT|NU|NYC|NZ|OBI|OFFICE|OKINAWA|OM|OMEGA|ONE|ONG|ONL|ONLINE|OOO|Oracle|ORANGE|ORG|ORGANIC|ORIGINS|OSAKA|OTSUKA|OVH|PA|PAGE|PAMPEREDCHEF|PANERAI|PARIS|PARS|PARTNERS|PARTS|PARTY|PE|PET|PF|PG|PH|PHARMACY|PHILIPS|PHOTO|PHOTOGRAPHY|PHOTOS|PHYSIO|PIAGET|PICS|PICTET|PICTURES|PID|PIN|PING|PINK|PIZZA|PK|PL|PLACE|PLAY|PlayStation|PLUMBING|PLUS|PM|PN|POHL|POKER|PORN|POST|PR|PRAXI|PRESS|PRO|PROD|PRODUCTIONS|PROF|PROMO|PROPERTIES|PROPERTY|PROTECTION|PS|PT|PUB|PW|PY|QA|QPON|QUEBEC|RACING|RE|READ|REALTOR|REALTY|RECIPES|RED|REDSTONE|REDUMBRELLA|REHAB|REISE|REISEN|REIT|REN|RENT|RENTALS|REPAIR|REPORT|REPUBLICAN|REST|RESTAURANT|REVIEW|REVIEWS|REXROTH|RICH|RICOH|RIO|RIP|RO|ROCHER|ROCKS|RODEO|ROOM|RS|RSVP|RU|RUHR|RUN|RW|RWE|RYUKYU|SA|SAARLAND|SAFE|SAFETY|SAKURA|SALE|SALON|SAMSUNG|SANDVIK|SANDVIKCOROMANT|SANOFI|SAP|SAPO|SARL|SAS|SAXO|SB|SBS|SC|SCA|SCB|SCHAEFFLER|SCHMIDT|SCHOLARSHIPS|SCHOOL|SCHULE|SCHWARZ|SCIENCE|SCOR|SCOT|SD|SE|SEAT|SECURITY|SEEK|SELECT|SENER|SERVICES|SEVEN|SEW|SEX|SEXY|SFR|SG|SH|SHARP|Shell|SHIA|SHIKSHA|SHOES|SHOW|SHRIRAM|SI|SINGLES|SITE|SJ|SK|SKI|SKIN|SKY|SKYPE|SL|SM|SMILE|SN|SNCF|SO|SOCCER|SOCIAL|SOFTBANK|SOFTWARE|SOHU|SOLAR|SOLUTIONS|SONY|SOY|SPACE|SPIEGEL|SPREADBETTING|SR|SRL|ST|STADA|STAR|STARHUB|STATEFARM|STATOIL|STC|STCGROUP|STOCKHOLM|STORAGE|STUDIO|STUDY|STYLE|SU|SUCKS|SUPPLIES|SUPPLY|SUPPORT|SURF|SURGERY|SUZUKI|SV|SWATCH|SWISS|SX|SY|SYDNEY|SYMANTEC|SYSTEMS|SZ|TAB|TAIPEI|TAOBAO|TATAMOTORS|TATAR|TATTOO|TAX|TAXI|TC|TCI|TD|TEAM|TECH|TECHNOLOGY|TEL|TELEFONICA|TEMASEK|TENNIS|TF|TG|TH|THD|THEATER|THEATRE|TICKETS|TIENDA|TIFFANY|TIPS|TIRES|TIROL|TJ|TK|TL|TM|TMALL|TN|TO|TODAY|TOKYO|TOOLS|TOP|TORAY|Toshiba|TOURS|TOWN|TOYOTA|TOYS|TR|TRADE|TRADING|TRAINING|TRAVEL|TRAVELERS|TRAVELERSINSURANCE|TRUST|TRV|TT|TUBE|TUI|TUSHU|TV|TW|TZ|UA|UBS|UG|UK|UNIVERSITY|UNO|UOL|US|UY|UZ|VA|VACATIONS|VANA|VC|VE|VEGAS|VENTURES|VERISIGN|VERSICHERUNG|VET|VG|VI|VIAJES|VIDEO|VILLAS|VIN|VIP|VIRGIN|VISION|Vista|VISTAPRINT|VIVA|VLAANDEREN|VN|VODKA|VOLKSWAGEN|VOTE|VOTING|VOTO|VOYAGE|VU|WALES|WALTER|WANG|WANGGOU|WATCH|WATCHES|WEATHER|WEBCAM|WEBER|WEBSITE|WED|WEDDING|WEIR|WF|WHOSWHO|WIEN|WIKI|WILLIAMHILL|WIN|WINDOWS|WINE|WME|WORK|WORKS|WORLD|WS|WTC|WTF|XBOX|XEROX|XIN|XN--11B4C3D|XN--1QQW23A|XN--30RR7Y|XN--3BST00M|XN--3DS443G|XN--3E0B707E|XN--3PXU8K|XN--42C2D9A|XN--45BRJ9C|XN--45Q11C|XN--4GBRIM|XN--55QW42G|XN--55QX5D|XN--6FRZ82G|XN--6QQ986B3XL|XN--80ADXHKS|XN--80AO21A|XN--80ASEHDB|XN--80ASWG|XN--90A3AC|XN--90AIS|XN--9DBQ2A|XN--9ET52U|XN--B4W605FERD|XN--C1AVG|XN--C2BR7G|XN--CG4BKI|XN--CLCHC0EA0B2G2A9GCD|XN--CZR694B|XN--CZRS0T|XN--CZRU2D|XN--D1ACJ3B|XN--D1ALF|XN--ECKVDTC9D|XN--EFVY88H|XN--ESTV75G|XN--FHBEI|XN--FIQ228C5HS|XN--FIQ64B|XN--FIQS8S|XN--FIQZ9S|XN--FJQ720A|XN--FLW351E|XN--FPCRJ9C3D|XN--FZC2C9E2C|XN--G2XX48C|XN--GECRJ9C|XN--H2BRJ9C|XN--HXT814E|XN--I1B6B1A6A2E|XN--IMR513N|XN--IO0A7I|XN--J1AEF|XN--J1AMH|XN--J6W193G|XN--JLQ61U9W7B|XN--KCRX77D1X4A|XN--KPRW13D|XN--KPRY57D|XN--KPU716F|XN--KPUT3I|XN--L1ACC|XN--LGBBAT1AD8J|XN--MGB9AWBF|XN--MGBA3A3EJT|XN--MGBA3A4F16A|XN--MGBAAM7A8H|XN--MGBAB2BD|XN--MGBAYH7GPA|XN--MGBB9FBPOB|XN--MGBBH1A71E|XN--MGBC0A9AZCG|XN--MGBERP4A5D4AR|XN--MGBPL2FH|XN--MGBT3DHD|XN--MGBTX2B|XN--MGBX4CD0AB|XN--MK1BU44C|XN--MXTQ1M|XN--NGBC5AZD|XN--NGBE9E0A|XN--NODE|XN--NQV7F|XN--NQV7FS00EMA|XN--NYQY26A|XN--O3CW4H|XN--OGBPF8FL|XN--P1ACF|XN--P1AI|XN--PBT977C|XN--PGBS0DH|XN--PSSY2U|XN--Q9JYB4C|XN--QCKA1PMC|XN--QXAM|XN--RHQV96G|XN--S9BRJ9C|XN--SES554G|XN--T60B56A|XN--TCKWE|XN--UNUP4Y|XN--VERMGENSBERATER-CTB|XN--VERMGENSBERATUNG-PWB|XN--VHQUV|XN--VUQ861B|XN--WGBH1C|XN--WGBL6A|XN--XHQ521B|XN--XKC2AL3HYE2A|XN--XKC2DL3A5EE0H|XN--Y9A3AQ|XN--YFRO4I67O|XN--YGBI2AMMX|XN--ZFR164B|XPERIA|XXX|XYZ|YACHTS|YAMAXUN|YANDEX|YE|YODOBASHI|YOGA|YOKOHAMA|YOUTUBE|YT|ZA|ZARA|ZERO|Zip|ZM|ZONE|ZUERICH|ZW)\b

Điều đó dễ dàng loại bỏ các email như [email protected], [email protected] vv

Tên miền có thể được chỉnh sửa thêm nếu cần, ví dụ: tên miền quốc gia cụ thể, vv.

4
SIslam

Hiện tại có nhiều hơn (1000) TLD. Hầu hết các câu trả lời ở đây cần phải được bỏ phiếu vì chúng không còn đúng nữa - có khả năng câu hỏi này nên có phiên bản thứ 2.

Vui lòng truy cập một cuộc thảo luận mới hơn về bài đăng khác ... .

4
David Levy

Đối với PHP Tôi đang sử dụng trình xác thực địa chỉ email từ Nette Framework - http://api.nette.org/2.3.3/source-Utils.Validators.php.html#234-247

/* public static */ function isEmail($value)
{
    $atom = "[-a-z0-9!#$%&'*+/=?^_`{|}~]"; // RFC 5322 unquoted characters in local-part
    $localPart = "(?:\"(?:[ !\\x23-\\x5B\\x5D-\\x7E]*|\\\\[ -~])+\"|$atom+(?:\\.$atom+)*)"; // quoted or unquoted
    $alpha = "a-z\x80-\xFF"; // superset of IDN
    $domain = "[0-9$alpha](?:[-0-9$alpha]{0,61}[0-9$alpha])?"; // RFC 1034 one domain component
    $topDomain = "[$alpha](?:[-0-9$alpha]{0,17}[$alpha])?";
    return (bool) preg_match("(^[email protected](?:$domain\\.)+$topDomain\\z)i", $value);
}
4
Ondřej Šotek

Chúng tôi đã sử dụng http://www.aspnetmx.com/ với mức độ thành công trong một vài năm nay. Bạn có thể chọn mức độ bạn muốn xác thực tại (ví dụ: kiểm tra cú pháp, kiểm tra tên miền, bản ghi mx hoặc email thực tế).

Đối với các biểu mẫu mặt trước, chúng tôi thường xác minh rằng tên miền tồn tại và cú pháp là chính xác, sau đó chúng tôi xác minh chặt chẽ hơn để dọn sạch cơ sở dữ liệu của chúng tôi trước khi thực hiện gửi thư hàng loạt.

4
cbp

Danh sách mục

Tôi sử dụng chức năng này 

function checkmail($value){
        $value = trim($value);
        if( stristr($value,"@") 
            && stristr($value,".") 
            && (strrpos($value, ".") - stripos($value, "@") > 2) 
            && (stripos($value, "@") > 1) 
            && (strlen($value) - strrpos($value, ".") < 6) 
            && (strlen($value) - strrpos($value, ".") > 2) 
            && ($value == preg_replace('/[ ]/', '', $value)) 
            && ($value == preg_replace('/[^A-Za-z0-9\[email protected]!*]/', '', $value))
        ){

        }else{
            return "Invalid Mail-Id";
        }
    }
3
Prassd Nidode

Tôi đã tìm thấy Bài viết hay , trong đó nói rằng cách tốt nhất để xác thực địa chỉ email là biểu thức regex đó: /[email protected]+\..+/i

3
syp_dino

Tôi hoàn toàn không đề xuất sử dụng regex - địa chỉ email quá phức tạp cho việc đó. Đây là một vấn đề phổ biến vì vậy tôi đoán có nhiều thư viện chứa trình xác nhận hợp lệ - nếu bạn sử dụng Java thì EmailValidator of Trình xác thực commons của Apache là một thư viện tốt.

3
Hans-Peter Störr

Quy tắc này phù hợp với những gì máy chủ postfix của chúng tôi không thể gửi đến.

cho phép chữ cái, số, -, _, +,., &,/,!

không [email protected]

không có [email protected]

/^([a-z0-9\+\._\/&!][-a-z0-9\+\._\/&!]*)@(([a-z0-9][-a-z0-9]*\.)([-a-z0-9]+\.)*[a-z]{2,})$/i
3
grosser

hmm lạ không thấy câu trả lời này đã có trong câu trả lời. Đây là phiên bản tôi đã xây dựng . Đây không phải là phiên bản chống đạn nhưng nó 'đơn giản' và kiểm tra hầu hết mọi thứ.

[\w+-]+(?:\.[\w+-]+)*@[\w+-]+(?:\.[\w+-]+)*(?:\.[a-zA-Z]{2,4})

Tôi nghĩ rằng một lời giải thích được đưa ra để bạn có thể sửa đổi nó nếu bạn muốn:

( e ) [\w+-]+ khớp với a-z, A-Z, _, +, - ít nhất một lần 

( m ) (?:\.[\w+-]+)* khớp với a-z, A-Z, _, +, - 0 hoặc nhiều lần nhưng cần bắt đầu bằng a. (dấu chấm) 

@ = @

( i ) [\w+-]+ khớp với a-z, A-Z, _, +, - ít nhất một lần 

( l ) (?:\.[\w+-]+)* khớp với a-z, A-Z, _, +, - 0 hoặc nhiều lần nhưng cần bắt đầu bằng a. (dấu chấm) 

( com ) (?:\.[a-zA-Z]{2,4}) khớp với a-z, A-Z trong 2 đến 4 lần bắt đầu bằng a. (dấu chấm)

đưa ra e(.m)@i(.l).com trong đó (.m)(.l) là tùy chọn nhưng cũng có thể được lặp lại nhiều lần .

lưu ý điều này sẽ cho phép [email protected] nhưng đó là sự thỏa hiệp để giữ cho nó đơn giản.

3
FLY

Không ai đề cập đến vấn đề nội địa hóa (i18), nếu bạn có khách hàng đến từ khắp nơi trên thế giới thì sao? Sau đó, bạn sẽ cần phân loại regex theo quốc gia/khu vực mà tôi đã thấy các nhà phát triển kết thúc việc xây dựng một từ điển/cấu hình lớn. Phát hiện cài đặt ngôn ngữ trình duyệt của người dùng có thể là điểm khởi đầu tốt.

3
Jay Zeng

Các biểu thức chính quy được đăng trong chủ đề này hiện đã lỗi thời do các tên miền cấp cao chung mới (gTLD) xuất hiện (ví dụ: .london, .basketball ,. 通 販). Để xác thực một địa chỉ email có hai câu trả lời (Điều đó có liên quan đến đại đa số).

  1. Như câu trả lời chính nói - không sử dụng biểu thức chính quy, chỉ cần xác thực nó bằng cách gửi email đến địa chỉ (Bắt ngoại lệ cho các địa chỉ không hợp lệ)
  2. Sử dụng một regex rất chung chung để ít nhất đảm bảo rằng họ đang sử dụng cấu trúc email {something}@{something}.{something}. Sẽ không có lý do gì để có một regex chi tiết vì bạn sẽ không nắm bắt được tất cả và sẽ có một đợt mới trong một vài năm và bạn sẽ phải cập nhật lại biểu thức thường xuyên của mình.

Tôi đã quyết định sử dụng biểu thức chính quy bởi vì, thật không may, một số người dùng không đọc biểu mẫu và đặt dữ liệu sai vào các trường sai. Điều này ít nhất sẽ cảnh báo họ khi họ cố gắng đưa thứ gì đó không phải là email vào trường nhập email và sẽ giúp bạn tiết kiệm thời gian hỗ trợ người dùng về các vấn đề email.

(.+)@(.+){2,}\.(.+){2,}
3
McGaz

Theo RFC 2821RFC 2822 , phần cục bộ của địa chỉ email có thể sử dụng bất kỳ ký tự ASCII nào sau đây: 

  1. Chữ viết hoa và chữ cái
  2. Các chữ số từ 0 đến 9 
  3. Các ký tự ,! # $% & '* + -/=? ^ _ `{|} ~ 
  4. Nhân vật "." với điều kiện nó không phải là ký tự đầu tiên hoặc cuối cùng trong phần cục bộ.

Kết quả phù hợp: 

Không phù hợp:

Đối với một trong đó là RFC 2821, 2822 Tuân thủ bạn có thể sử dụng:

^((([!#$%&'*+\-/=?^_`{|}~\w])|([!#$%&'*+\-/=?^_`{|}~\w][!#$%&'*+\-/=?^_`{|}~\.\w]{0,}[!#$%&'*+\-/=?^_`{|}~\w]))[@]\w+([-.]\w+)*\.\w+([-.]\w+)*)$

Email - RFC 2821, 2822 Tuân thủ

2
Dave Black

API Java Mail làm phép thuật cho chúng tôi. 

try
    {
     InternetAddress internetAddress = new InternetAddress(email);
     internetAddress.validate();
     return true;
    }
    catch(Exception ex)
    {
        return false;
    }

Tôi đã nhận được điều này từ ở đây

2
sunleo

Nếu bạn muốn cải thiện một regex đã hoạt động khá tốt trong nhiều năm, thì câu trả lời phụ thuộc vào chính xác những gì bạn muốn đạt được - loại địa chỉ email nào đã bị lỗi. Tinh chỉnh email regexes là rất khó, và tôi vẫn chưa thấy một giải pháp hoàn hảo.

  • Nếu ứng dụng của bạn liên quan đến một cái gì đó rất kỹ thuật (hoặc một cái gì đó bên trong các tổ chức), thì có lẽ bạn cần hỗ trợ địa chỉ IP thay vì tên miền hoặc nhận xét trong phần "cục bộ" của địa chỉ email.
  • Nếu ứng dụng của bạn là đa quốc gia, tôi sẽ xem xét tập trung vào hỗ trợ Unicode/UTF8.

Câu trả lời hàng đầu cho câu hỏi của bạn hiện liên kết đến "regex tuân thủ RFC 22 822 đầy đủ". Tuy nhiên, bất chấp sự phức tạp của regex đó và sự chú ý của nó đến chi tiết trong các quy tắc RFC, nó hoàn toàn thất bại khi hỗ trợ Unicode.

Regex mà tôi đã viết cho hầu hết các ứng dụng của mình tập trung vào hỗ trợ Unicode, cũng như hợp lý tuân thủ tốt các tiêu chuẩn RFC:

/^(?!\.)((?!.*\.{2})[a-zA-Z0-9\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u0250-\u02AF\u0300-\u036F\u0370-\u03FF\u0400-\u04FF\u0500-\u052F\u0530-\u058F\u0590-\u05FF\u0600-\u06FF\u0700-\u074F\u0750-\u077F\u0780-\u07BF\u07C0-\u07FF\u0900-\u097F\u0980-\u09FF\u0A00-\u0A7F\u0A80-\u0AFF\u0B00-\u0B7F\u0B80-\u0BFF\u0C00-\u0C7F\u0C80-\u0CFF\u0D00-\u0D7F\u0D80-\u0DFF\u0E00-\u0E7F\u0E80-\u0EFF\u0F00-\u0FFF\u1000-\u109F\u10A0-\u10FF\u1100-\u11FF\u1200-\u137F\u1380-\u139F\u13A0-\u13FF\u1400-\u167F\u1680-\u169F\u16A0-\u16FF\u1700-\u171F\u1720-\u173F\u1740-\u175F\u1760-\u177F\u1780-\u17FF\u1800-\u18AF\u1900-\u194F\u1950-\u197F\u1980-\u19DF\u19E0-\u19FF\u1A00-\u1A1F\u1B00-\u1B7F\u1D00-\u1D7F\u1D80-\u1DBF\u1DC0-\u1DFF\u1E00-\u1EFF\u1F00-\u1FFFu20D0-\u20FF\u2100-\u214F\u2C00-\u2C5F\u2C60-\u2C7F\u2C80-\u2CFF\u2D00-\u2D2F\u2D30-\u2D7F\u2D80-\u2DDF\u2F00-\u2FDF\u2FF0-\u2FFF\u3040-\u309F\u30A0-\u30FF\u3100-\u312F\u3130-\u318F\u3190-\u319F\u31C0-\u31EF\u31F0-\u31FF\u3200-\u32FF\u3300-\u33FF\u3400-\u4DBF\u4DC0-\u4DFF\u4E00-\u9FFF\uA000-\uA48F\uA490-\uA4CF\uA700-\uA71F\uA800-\uA82F\uA840-\uA87F\uAC00-\uD7AF\uF900-\uFAFF\.!#$%&'*+-/=?^_`{|}~\-\d]+)@(?!\.)([a-zA-Z0-9\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u0250-\u02AF\u0300-\u036F\u0370-\u03FF\u0400-\u04FF\u0500-\u052F\u0530-\u058F\u0590-\u05FF\u0600-\u06FF\u0700-\u074F\u0750-\u077F\u0780-\u07BF\u07C0-\u07FF\u0900-\u097F\u0980-\u09FF\u0A00-\u0A7F\u0A80-\u0AFF\u0B00-\u0B7F\u0B80-\u0BFF\u0C00-\u0C7F\u0C80-\u0CFF\u0D00-\u0D7F\u0D80-\u0DFF\u0E00-\u0E7F\u0E80-\u0EFF\u0F00-\u0FFF\u1000-\u109F\u10A0-\u10FF\u1100-\u11FF\u1200-\u137F\u1380-\u139F\u13A0-\u13FF\u1400-\u167F\u1680-\u169F\u16A0-\u16FF\u1700-\u171F\u1720-\u173F\u1740-\u175F\u1760-\u177F\u1780-\u17FF\u1800-\u18AF\u1900-\u194F\u1950-\u197F\u1980-\u19DF\u19E0-\u19FF\u1A00-\u1A1F\u1B00-\u1B7F\u1D00-\u1D7F\u1D80-\u1DBF\u1DC0-\u1DFF\u1E00-\u1EFF\u1F00-\u1FFF\u20D0-\u20FF\u2100-\u214F\u2C00-\u2C5F\u2C60-\u2C7F\u2C80-\u2CFF\u2D00-\u2D2F\u2D30-\u2D7F\u2D80-\u2DDF\u2F00-\u2FDF\u2FF0-\u2FFF\u3040-\u309F\u30A0-\u30FF\u3100-\u312F\u3130-\u318F\u3190-\u319F\u31C0-\u31EF\u31F0-\u31FF\u3200-\u32FF\u3300-\u33FF\u3400-\u4DBF\u4DC0-\u4DFF\u4E00-\u9FFF\uA000-\uA48F\uA490-\uA4CF\uA700-\uA71F\uA800-\uA82F\uA840-\uA87F\uAC00-\uD7AF\uF900-\uFAFF\-\.\d]+)((\.([a-zA-Z\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u0250-\u02AF\u0300-\u036F\u0370-\u03FF\u0400-\u04FF\u0500-\u052F\u0530-\u058F\u0590-\u05FF\u0600-\u06FF\u0700-\u074F\u0750-\u077F\u0780-\u07BF\u07C0-\u07FF\u0900-\u097F\u0980-\u09FF\u0A00-\u0A7F\u0A80-\u0AFF\u0B00-\u0B7F\u0B80-\u0BFF\u0C00-\u0C7F\u0C80-\u0CFF\u0D00-\u0D7F\u0D80-\u0DFF\u0E00-\u0E7F\u0E80-\u0EFF\u0F00-\u0FFF\u1000-\u109F\u10A0-\u10FF\u1100-\u11FF\u1200-\u137F\u1380-\u139F\u13A0-\u13FF\u1400-\u167F\u1680-\u169F\u16A0-\u16FF\u1700-\u171F\u1720-\u173F\u1740-\u175F\u1760-\u177F\u1780-\u17FF\u1800-\u18AF\u1900-\u194F\u1950-\u197F\u1980-\u19DF\u19E0-\u19FF\u1A00-\u1A1F\u1B00-\u1B7F\u1D00-\u1D7F\u1D80-\u1DBF\u1DC0-\u1DFF\u1E00-\u1EFF\u1F00-\u1FFF\u20D0-\u20FF\u2100-\u214F\u2C00-\u2C5F\u2C60-\u2C7F\u2C80-\u2CFF\u2D00-\u2D2F\u2D30-\u2D7F\u2D80-\u2DDF\u2F00-\u2FDF\u2FF0-\u2FFF\u3040-\u309F\u30A0-\u30FF\u3100-\u312F\u3130-\u318F\u3190-\u319F\u31C0-\u31EF\u31F0-\u31FF\u3200-\u32FF\u3300-\u33FF\u3400-\u4DBF\u4DC0-\u4DFF\u4E00-\u9FFF\uA000-\uA48F\uA490-\uA4CF\uA700-\uA71F\uA800-\uA82F\uA840-\uA87F\uAC00-\uD7AF\uF900-\uFAFF]){2,63})+)$/i

Tôi sẽ tránh sao chép các câu trả lời hoàn chỉnh, vì vậy tôi sẽ chỉ liên kết câu trả lời này với một câu trả lời tương tự tôi đã cung cấp ở đây: Làm thế nào để xác thực một email unicode?

Ngoài ra còn có một bản demo trực tiếp có sẵn cho regex ở trên tại: http://jsfiddle.net/aossikine/qCLVH/3/

2
Alexey Ossikine

Phải đề cập đến, gần như đã được thêm tên miền mới "yandex". Email có thể: [email protected] Và cũng là chữ cái viết hoa được hỗ trợ, do đó, một phiên bản sửa đổi của giải pháp acrosman là:

^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,6})$
2
Fragment

Một regex thực hiện chính xác những gì các tiêu chuẩn nói được cho phép, theo những gì tôi đã thấy về chúng, là:

/^(?!(^[.-].*|.*[.-]@|.*\.{2,}.*)|^.{254}[email protected])([a-z\xC0-\xFF0-9!#$%&'*+\/=?^_`{|}~.-][email protected])(?!.{253}.+$)((?!-.*|.*-\.)([a-z0-9-]{1,63}\.)+[a-z]{2,63}|(([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])\.){3}([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9]))$/gim

Demo_/Phân tích Debuggex ( tương tác )

Chia ra:

^(?!(^[.-].*|.*[.-]@|.*\.{2,}.*)|^.{254}[email protected])
([a-z\xC0-\xFF0-9!#$%&'*+\/=?^_`{|}~.-][email protected])
(?!.{253}.+$)
(
    (?!-.*|.*-\.)
    ([a-z0-9-]{1,63}\.)+
    [a-z]{2,63}
    |
    (([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])\.){3}
    ([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])
)$

Phân tích:

(?!(^[.-].*|.*[.-]@|.*\.{2,}.*)|^.{254}[email protected])

Cái nhìn tiêu cực cho một trong hai một địa chỉ bắt đầu bằng ., kết thúc bằng một, có .. trong đó hoặc vượt quá độ dài tối đa 254 ký tự


([a-z\xC0-\xFF0-9!#$%&'*+\/=?^_`{|}~.-][email protected])

khớp 1 hoặc nhiều hơn ký tự được phép , với giao diện phủ định áp dụng cho nó


(?!.{253}.+$)

Cái nhìn tiêu cực cho phần tên miền, giới hạn nó ở tổng cộng có 255 ký tự


(?!-.*|.*-\.)

Cái nhìn tiêu cực cho từng tên miền không cho phép bắt đầu hoặc kết thúc bằng .


([a-z0-9-]{1,63}\.)+

khớp nhóm đơn giản cho các ký tự được phép trong một tên miền, được giới hạn ở mỗi ký tự 63 ký tự


[a-zA-Z]{2,63}

kết hợp nhóm đơn giản cho miền cấp cao nhất được phép, hiện tại tĩnh chỉ bị giới hạn ở các chữ cái, nhưng không bao gồm> 4 TLD chữ cái .


(([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])\.){3}
([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])

thay thế cho tên miền: số này khớp với 3 số đầu tiên trong địa chỉ IP với a . phía sau, và sau đó là số thứ tư trong địa chỉ IP không có . phía sau.

1
Joeytje50

Như đã đề cập, bạn không thể xác thực một email với biểu thức chính quy. Tuy nhiên, đây là những gì chúng tôi hiện đang sử dụng để đảm bảo đầu vào của người dùng không hoàn toàn không có thật (quên TLD, v.v.).

Regex này sẽ cho phép các tên miền IDN và các ký tự đặc biệt (như Umlauts) trước và sau dấu @.

/^[\w.+-_][email protected][^.][\w.-]*\.[\w-]{2,63}$/iu
1
zıəs uɐɟəʇs

Nền tảng viết blog phổ biến nhất thế giới WordPress sử dụng chức năng này để xác thực địa chỉ email ..

Nhưng họ đang làm điều đó với nhiều bước. 

Bạn không phải lo lắng nữa khi sử dụng regex được đề cập trong chức năng này .. 

Đây là chức năng .. 

/**
 * Verifies that an email is valid.
 *
 * Does not grok i18n domains. Not RFC compliant.
 *
 * @since 0.71
 *
 * @param string $email Email address to verify.
 * @param boolean $deprecated Deprecated.
 * @return string|bool Either false or the valid email address.
 */
function is_email( $email, $deprecated = false ) {
    if ( ! empty( $deprecated ) )
        _deprecated_argument( __FUNCTION__, '3.0' );

    // Test for the minimum length the email can be
    if ( strlen( $email ) < 3 ) {
        return apply_filters( 'is_email', false, $email, 'email_too_short' );
    }

    // Test for an @ character after the first position
    if ( strpos( $email, '@', 1 ) === false ) {
        return apply_filters( 'is_email', false, $email, 'email_no_at' );
    }

    // Split out the local and domain parts
    list( $local, $domain ) = explode( '@', $email, 2 );

    // LOCAL PART
    // Test for invalid characters
    if ( !preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local ) ) {
        return apply_filters( 'is_email', false, $email, 'local_invalid_chars' );
    }

    // DOMAIN PART
    // Test for sequences of periods
    if ( preg_match( '/\.{2,}/', $domain ) ) {
        return apply_filters( 'is_email', false, $email, 'domain_period_sequence' );
    }

    // Test for leading and trailing periods and whitespace
    if ( trim( $domain, " \t\n\r\0\x0B." ) !== $domain ) {
        return apply_filters( 'is_email', false, $email, 'domain_period_limits' );
    }

    // Split the domain into subs
    $subs = explode( '.', $domain );

    // Assume the domain will have at least two subs
    if ( 2 > count( $subs ) ) {
        return apply_filters( 'is_email', false, $email, 'domain_no_periods' );
    }

    // Loop through each sub
    foreach ( $subs as $sub ) {
        // Test for leading and trailing hyphens and whitespace
        if ( trim( $sub, " \t\n\r\0\x0B-" ) !== $sub ) {
            return apply_filters( 'is_email', false, $email, 'sub_hyphen_limits' );
        }

        // Test for invalid characters
        if ( !preg_match('/^[a-z0-9-]+$/i', $sub ) ) {
            return apply_filters( 'is_email', false, $email, 'sub_invalid_chars' );
        }
    }

    // Congratulations your email made it!
    return apply_filters( 'is_email', $email, $email, null );
}
1
Giri

Sau đây là biểu thức chính quy để xác thực địa chỉ email

^[email protected]\w+(\.\w+)+$
1
Prasad Bhosale

Tôi đã có một mong muốn tương tự: muốn kiểm tra nhanh cú pháp trong các địa chỉ email mà không cần quá nhiệt tình (câu trả lời Mail::RFC822::Address là câu trả lời rõ ràng chính xác) cho tiện ích gửi email . Tôi đã thực hiện điều này (Tôi là một người POSIX RE vì vậy tôi thường không sử dụng \d và như vậy từ PCRE, vì họ làm cho mọi thứ trở nên dễ đọc hơn đối với tôi):

preg_match("_^[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*@[0-9A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z])?)*\$_", $adr)

Đây là RFC chính xác nhưng loại trừ rõ ràng các hình thức lỗi thời cũng như IP trực tiếp (cả IP và Legacy IP), mà ai đó trong nhóm mục tiêu của tiện ích đó (chủ yếu: những người làm phiền chúng tôi trong #sendmail trên IRC) thường không muốn hoặc dù sao cũng cần.

IDN (tên miền được quốc tế hóa) rõ ràng là không trong phạm vi của email: địa chỉ như mật [email protected]äcilienchor-bonn.de tựa phải được viết bằng văn bản Thay vào đó, trên mạng (điều này bao gồm các liên kết mailto: vui nhộn như vậy), chỉ GUI mới được phép hiển thị (và chấp nhận sau đó chuyển đổi) các tên đó thành (và từ) người dùng.

1
mirabilos

Thật tuyệt, tôi đã chuyển đổi mã thành Java để phù hợp với trình biên dịch

String pattern ="(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?|\\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-zA-Z0-9-]*[a-zA-Z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])";
1
Hany Sakr

Tôi đã tìm thấy một biểu thức chính quy tuân thủ RFC 2822. Tiêu chuẩn trước cho RFC 5322. Biểu thức chính quy này dường như hoạt động khá tốt và sẽ bao gồm hầu hết các trường hợp, tuy nhiên với RFC 5322 trở thành tiêu chuẩn có thể có một số lỗ hổng nên được cắm.

^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$

Các tài liệu nói rằng bạn không nên sử dụng các biểu thức thông thường ở trên, nhưng thay vào đó ủng hộ hương vị này, dễ quản lý hơn một chút.

[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?

Tôi nhận thấy đây là trường hợp nhạy cảm, vì vậy tôi thực sự đã thực hiện một thay đổi cho lần hạ cánh này.

^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$
1
mrswadge

RegEx hợp lệ theo w3 orgwikipedia

[A-Z0-9a-z.!#$%&'*+-/=?^_`{|}~][email protected][A-Za-z0-9.-]+\\.[A-Za-z]{2,4}

ví dụ. !#$%&'*+-/=?ucci_`.

0
Rajneesh071

Tôi sử dụng cái này;

^(([^<>()\[\]\\.,;:\[email protected]"]+(\.[^<>()\[\]\\.,;:\[email protected]"]+)*)|(".+"))@((\[[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,}))$
0
Savas Adar

regex email (RFC5322)

(?im)^(?=.{1,64}@)(?:("[^"\\]*(?:\\.[^"\\]*)*"@)|((?:[0-9a-z](?:\.(?!\.)|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)?[0-9a-z]@))(?=.{1,255}$)(?:(\[(?:\d{1,3}\.){3}\d{1,3}\])|((?:(?=.{1,63}\.)[0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9])|((?=.{1,63}$)[0-9a-z][-\w]*))$

Bản trình diễn https://regex101.com/r/ObS3QZ/1

 # (?im)^(?=.{1,64}@)(?:("[^"\\]*(?:\\.[^"\\]*)*"@)|((?:[0-9a-z](?:\.(?!\.)|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)?[0-9a-z]@))(?=.{1,255}$)(?:(\[(?:\d{1,3}\.){3}\d{1,3}\])|((?:(?=.{1,63}\.)[0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9])|((?=.{1,63}$)[0-9a-z][-\w]*))$

 # Note - remove all comments '(comments)' before runninig this regex
 # Find  \([^)]*\)  replace with nothing

 (?im)                                     # Case insensitive
 ^                                         # BOS

                                           # Local part
 (?= .{1,64} @ )                           # 64 max chars
 (?:
      (                                         # (1 start), Quoted
           " [^"\\]* 
           (?: \\ . [^"\\]* )*
           "
           @
      )                                         # (1 end)
   |                                          # or, 
      (                                         # (2 start), Non-quoted
           (?:
                [0-9a-z] 
                (?:
                     \.
                     (?! \. )
                  |                                          # or, 
                     [-!#\$%&'\*\+/=\?\^`\{\}\|~\w] 
                )*
           )?
           [0-9a-z] 
           @
      )                                         # (2 end)
 )
                                           # Domain part
 (?= .{1,255} $ )                          # 255 max chars
 (?:
      (                                         # (3 start), IP
           \[
           (?: \d{1,3} \. ){3}
           \d{1,3} \]
      )                                         # (3 end)
   |                                          # or,   
      (                                         # (4 start), Others
           (?:                                       # Labels (63 max chars each)
                (?= .{1,63} \. )
                [0-9a-z] [-\w]* [0-9a-z]* 
                \.
           )+
           [a-z0-9] [\-a-z0-9]{0,22} [a-z0-9] 
      )                                         # (4 end)
   |                                          # or,
      (                                         # (5 start), Localdomain
           (?= .{1,63} $ )
           [0-9a-z] [-\w]* 
      )                                         # (5 end)
 )
 $                                         # EOS
0
sln

Bạn có thể sử dụng Biểu thức thông thường sau cho bất kỳ địa chỉ email nào

^(([^<>()[\]\\.,;:\[email protected]\"]+(\.[^<>()[\]\\.,;:\[email protected]\"]+)*)|(\".+\"))@((\[[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,}))$

Đối với PHP

  function checkEmailValidation($email)
  {         
       $expression='/^(([^<>()[\]\\.,;:\[email protected]\"]+(\.[^<>()[\]\\.,;:\[email protected]\"]+)*)|(\".+\"))@((\[[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,}))$/';
        if(preg_match($expression, $email))
        {
            return true;
        }else
        {
            return false;
        }
   }

Đối với Javascript

 function checkEmailValidation(email)
  {         
        var pattern='/^(([^<>()[\]\\.,;:\[email protected]\"]+(\.[^<>()[\]\\.,;:\[email protected]\"]+)*)|(\".+\"))@((\[[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,}))$/';
        if(pattern.test(email))
        {
            return true;
        }else
        {
            return false;
        }
   }
0
Ramesh Kotkar
^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.(([0-9]{1,3})|([a-zA-Z]{2,3})|(aero|coop|info|museum|name))$

Điều này khớp với 99,99% địa chỉ email, bao gồm một số tiện ích mở rộng tên miền cấp cao mới hơn, chẳng hạn như thông tin, bảo tàng, tên, v.v. Nó cũng cho phép các email được gắn trực tiếp vào địa chỉ IP.

0
Francisco Tomé Costa

Viết một biểu thức thường xuyên cho tất cả mọi thứ sẽ mất rất nhiều nỗ lực. Thay vào đó, bạn có thể sử dụng gói pyIsEmail .

Dưới đây văn bản được lấy từ pyIsEmail trang web.

pyIsEmail là một cách tiếp cận vô nghĩa để kiểm tra xem địa chỉ email do người dùng cung cấp có thể là thật hay không.

Các biểu thức thông thường rất rẻ để viết, nhưng thường yêu cầu bảo trì khi các tên miền cấp cao mới xuất hiện hoặc không phù hợp với các tính năng địa chỉ email trở lại thịnh hành. pyIsEmail cho phép bạn xác thực một địa chỉ email - và thậm chí kiểm tra tên miền, nếu bạn muốn - chỉ với một cuộc gọi đơn giản, làm cho mã của bạn dễ đọc hơn và viết nhanh hơn. Khi bạn muốn biết lý do tại sao một địa chỉ email không xác thực, họ thậm chí còn cung cấp cho bạn chẩn đoán.

Sử dụng

Để sử dụng đơn giản nhất, nhập và sử dụng hàm is_email:

from pyisemail import is_email

address = "[email protected]"
bool_result = is_email(address)
detailed_result = is_email(address, diagnose=True)

Bạn cũng có thể kiểm tra xem tên miền được sử dụng trong email có phải là tên miền hợp lệ hay không và liệu nó có bản ghi MX hợp lệ hay không:

from pyisemail import is_email

address = "[email protected]"
bool_result_with_dns = is_email(address, check_dns=True)
detailed_result_with_dns = is_email(address, check_dns=True, diagnose=True)

Đây là những chỉ số chính về việc một địa chỉ email thậm chí có thể được phát hành tại tên miền đó hay không. Tuy nhiên, một phản hồi hợp lệ ở đây không phải là sự đảm bảo rằng email tồn tại, chỉ đơn thuần là có thể tồn tại.

Ngoài chức năng is_email cơ sở, bạn cũng có thể tự mình sử dụng các trình xác nhận. Kiểm tra tài liệu nguồn trình xác nhận để xem cách thức hoạt động của nó.

0
partoftheorigin