정규식을 사용하여 이메일 주소를 확인하는 방법은 무엇입니까?

Oct 14 2008

수년 동안 나는 서버 부분으로 IP 주소를 사용하지 않는다는 가정하에 대부분의 이메일 주소를 올바르게 검증 하는 정규 표현식 을 천천히 개발했습니다 .

여러 PHP 프로그램에서 사용하며 대부분의 경우 작동합니다. 그러나 때때로 나는 그것을 사용하는 사이트에 문제가있는 누군가로부터 연락을 받고 결국 약간의 조정을해야합니다 (가장 최근에는 4 문자 TLD를 허용하지 않는다는 것을 깨달았습니다).

이메일을 확인하기 위해 가지고 있거나 본 적이있는 최고의 정규 표현식은 무엇입니까?

여러 개의 짧은 식을 사용하는 함수를 사용하는 여러 솔루션을 보았지만 더 복잡한 함수에서 여러 개의 짧은 식 대신 간단한 함수에서 하나의 긴 복잡한 식을 사용하는 것이 좋습니다.

답변

2561 bortzmeyer Oct 14 2008 at 21:26

완전히 RFC 822 호환 정규 표현식은 비효율적 때문에 길이의 불분명. 다행히 RFC 822는 두 번 대체되었으며 현재 이메일 주소 사양은 RFC 5322 입니다. RFC 5322는 몇 분 동안 연구하면 이해할 수 있고 실제 사용하기에 충분히 효율적인 정규식으로 이어집니다.

RFC 5322 준수 정규식 하나는 다음 페이지의 상단에서 찾을 수 있습니다. http://emailregex.com/그러나 00점으로 구분 된 주소에서 부호없는 바이트 십진수 값 을 허용하는 버그와 함께 인터넷 주위에 떠 다니는 IP 주소 패턴을 사용합니다 . 이는 불법입니다. 나머지 부분은 RFC 5322 문법과 일치하는 것으로 보이며 grep -Po사례 도메인 이름, IP 주소, 잘못된 이름 및 따옴표가 있거나없는 계정 이름을 포함 하여를 사용하여 여러 테스트를 통과했습니다 .

00IP 패턴 의 버그를 수정하여 작동하고 상당히 빠른 정규식을 얻습니다. (실제 코드의 경우 마크 다운이 아닌 렌더링 된 버전을 긁어냅니다.)

(? : [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])? | \ [(? :( ? :( 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]) +) \])

또는:

(?:[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])?|\[(?:(?:(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])+)\])

다음은 regexp 자체보다 더 명확한 위의 regexp에 대한 유한 상태 머신의 다이어그램 입니다.

Perl 및 PCRE (예 : PHP에서 사용되는 정규식 라이브러리)의보다 정교한 패턴 은 장애없이 RFC 5322를 올바르게 구문 분석 할 수 있습니다 . Python과 C #도 그렇게 할 수 있지만 처음 두 개와는 다른 구문을 사용합니다. 그러나 덜 강력한 패턴 일치 언어 중 하나를 사용해야하는 경우 실제 파서를 사용하는 것이 가장 좋습니다.

RFC에 따라 유효성을 검사해도 해당 주소가 제공된 도메인에 실제로 존재하는지 또는 주소를 입력하는 사람이 실제 소유자인지 여부에 대해 전혀 알려주지 않는다는 것을 이해하는 것도 중요합니다. 사람들은 항상 이런 식으로 메일 링리스트에 다른 사람을 등록합니다. 주소와 동일한 웹 페이지에 입력해야하는 확인 토큰이 포함 된 메시지를 해당 주소에 보내는 것과 관련된 더 멋진 종류의 유효성 검사가 필요한 수정입니다.

확인 토큰은 입력 한 사람의 주소를 알 수있는 유일한 방법입니다. 이것이 대부분의 메일 링리스트가 가입을 확인하는 데이 메커니즘을 사용하는 이유입니다. 결국, 누구든지를 내려 놓을 수 있으며 [email protected], 그것은 합법적 인 것으로 해석 될 것입니다.하지만 상대방이 될 가능성은 없습니다.

PHP의 경우 내가 인용 한 올바른 방법 인 PHP로 이메일 주소 확인에 제공된 패턴을 사용 해서는 안됩니다 .

일반적인 사용과 엉성한 코딩으로 인해 기록 된 공식 표준보다 더 제한적인 전자 메일 주소에 대한 사실상의 표준이 설정 될 위험이 있습니다.

다른 모든 비 RFC 패턴보다 낫지 않습니다. RFC 5322는 말할 것도없고 RFC 822 조차도 처리 할 수있을만큼 똑똑하지도 않습니다 . 그러나 이것은 그렇습니다 .

화려하고 현명하게 만들고 싶다면 완전한 상태 엔진을 구현하십시오 . 정규식은 기본 필터 역할 만 할 수 있습니다. 정규식의 문제점은 정규식이 처리 할 수 ​​없기 때문에 완벽하게 유효한 전자 메일 주소가 유효하지 않다고 (가양 성) 말하는 것은 사용자의 관점에서 볼 때 무례하고 무례하다는 것입니다. 이 목적을위한 상태 엔진은 각 RFC에 따라 전자 메일 주소를 분해하므로 유효하지 않은 것으로 간주되는 전자 메일 주소의 유효성을 검사하고 수정할 수 있습니다. 이것은 잠재적으로 더 즐거운 경험을 허용합니다.

지정된 이메일 주소 'myemail @ address, com'이 잘못되었습니다. [email protected] '을 의미 했습니까?

주석을 포함하여 이메일 주소 확인을 참조하십시오 . 또는 정규식을 검증하는 이메일 주소 비교 .

Debuggex 데모

769 SLaks Dec 15 2009 at 03:43

정규식을 사용하여 이메일 주소를 확인하면 안됩니다.

대신 다음과 같이 MailAddress 클래스를 사용하십시오 .

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

MailAddress클래스는 BNF 파서를 사용하여 RFC822에 따라 주소의 유효성을 검사합니다.

를 사용하여 MailAddress전자 메일 주소의 유효성을 검사하려는 경우이 방법은 전자 메일 주소의 표시 이름 부분도 허용하므로 원하는 결과가 아닐 수 있습니다. 예를 들어 다음 문자열을 유효한 전자 메일 주소로 허용합니다.

이러한 경우 중 일부에서는 문자열의 마지막 부분 만 주소로 구문 분석됩니다. 나머지는 표시 이름입니다. 표시 이름이없는 일반 전자 메일 주소를 얻으려면 정규화 된 주소를 원래 문자열과 비교하여 확인할 수 있습니다.

bool isValid = false;

try
{
    MailAddress address = new MailAddress(emailAddress);
    isValid = (address.Address == emailAddress);
    // or
    // isValid = string.IsNullOrEmpty(address.DisplayName);
}
catch (FormatException)
{
    // address is invalid
}

또한 끝에 점이있는 주소 user@company.는 MailAddress에서도 허용됩니다.

당신이 정말로 정규식을 사용하려면, 여기있다 :

(? : (? : \ 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 *)
548 JacquesB Oct 15 2008 at 02:40

이 질문은 많은 질문을 받지만 한 걸음 물러서서 이메일 주소를 구문 적으로 확인하고 싶은지 스스로에게 물어봐야한다고 생각합니다 . 실제로 어떤 이점이 있습니까?

  • 일반적인 오타를 포착하지 않습니다.
  • 사람들이 유효하지 않거나 구성된 이메일 주소를 입력하거나 다른 사람의 주소를 입력하는 것을 방지하지 않습니다.

이메일이 올바른지 확인하려면 확인 이메일을 보내고 사용자가 이에 응답하도록하는 것 외에는 선택의 여지가 없습니다. 많은 경우에 당신이 것 보안상의 이유로 윤리적 이유로 어쨌든 확인 메일을 보내 (그래서 할 수 있습니다 자신의 의지와 서비스까지하지 예를 들어, 기호 누군가).

389 AndyLester Oct 14 2008 at 21:42

그것은 모두 당신이 원하는 정도에 달려 있습니다. 내 목적을 위해 bob @ aol.com(이메일의 공백) 또는 steve(도메인 없음) 또는 mary@aolcom(.com 이전에 마침표 없음 ) 과 같은 것을 차단하려는 경우

/^\S+@\S+\.\S+$/

물론, 유효한 이메일 주소가 아닌 것과 일치하지만 일반적인 간단한 오류가 발생하는 문제입니다.

해당 정규식에 변경할 수있는 변경 사항이 많지만 (일부는이 답변에 대한 주석에 있음) 간단하고 이해하기 쉬우 며 좋은 첫 번째 시도입니다.

345 GoodPerson Apr 06 2009 at 02:39

최선의 의미에 따라 다릅니다. 유효한 모든 이메일 주소를 잡는 것에 대해 이야기하는 경우 다음을 사용하십시오.

(?:(?:\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) 더 간단한 것을 찾고 있지만 대부분의 유효한 이메일 주소를 잡을 수 있다면 다음과 같이 시도하십시오.

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

편집 : 링크에서 :

이 정규식은 주석이 제거되고 공백으로 대체 된 주소 만 유효성을 검사합니다 (모듈에서 수행됨).

288 DominicSayers Feb 10 2009 at 23:13

[업데이트 됨] 이메일 주소 확인에 대해 내가 아는 모든 것을 여기에 정리했습니다. http://isemail.info, 이제 이메일 주소의 유효성을 검사 할뿐만 아니라 문제도 진단합니다. 여기에서 유효성 검사가 답의 일부일 뿐이라는 많은 의견에 동의합니다. 내 에세이 참조http://isemail.info/about.

is_email ()은 내가 아는 한 주어진 문자열이 유효한 이메일 주소인지 아닌지를 확실히 알려주는 유일한 검증 자입니다. 새 버전을 업로드했습니다.http://isemail.info/

Cal Henderson, Dave Child, Phil Haack, Doug Lovell, RFC5322 및 RFC 3696의 테스트 케이스를 수집했습니다. 275 개의 테스트 주소가 모두 포함되어 있습니다. 내가 찾을 수있는 모든 무료 유효성 검사기에 대해이 모든 테스트를 실행했습니다.

사람들이 검증 인을 강화함에 따라이 페이지를 최신 상태로 유지하려고 노력할 것입니다. Cal, Michael, Dave, Paul 및 Phil에게 이러한 테스트를 컴파일하고 내 자신의 검증 인에 대한 건설적인 비판을 작성하는 데 도움과 협력을 해주신 것에 감사드립니다 .

사람들은 특히 RFC 3696 에 대한 정오표를 알고 있어야합니다 . 세 가지 표준 예는 실제로 잘못된 주소입니다. 그리고 주소의 최대 길이는 320자가 아니라 254 자 또는 256 자 입니다.

276 RoryO'Kane Jan 12 2012 at 09:24

당 은 W3C HTML5 사양 :

^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[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])?)*$

문맥:

유효한 이메일 주소 생산 ABNF [...]을 일치하는 문자열이다.

참고 :이 요구 사항은 RFC 5322에 대한 고의적 인 위반 으로 , 동시에 너무 엄격 ( "@"문자 앞), 너무 모호 ( "@"문자 뒤), 너무 느슨한 ( 대부분의 사용자에게 익숙하지 않은 방식으로 주석, 공백 문자 및 인용 된 문자열을 여기서 실제로 사용할 수 있습니다.

다음 JavaScript 및 Perl 호환 정규식은 위 정의를 구현 한 것입니다.

/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[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])?)*$/

201 Abigail Dec 17 2009 at 04:44

Perl 5.10 이상에서는 쉽습니다.

/(?(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
166 PerHornshøj-Schierbeck Oct 14 2008 at 21:17

나는 사용한다

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

RegularExpressionValidator가 ASP.NET에서 사용하는 것입니다.

142 ChristianVestHansen Oct 14 2008 at 21:17

최선에 대해 모르지만 주소의 주석이 제거되고 공백으로 대체되는 한 이것은 적어도 정확합니다.

진지하게. 이메일 검증을 위해 이미 작성된 라이브러리를 사용해야합니다. 가장 좋은 방법은 해당 주소로 확인 이메일을 보내는 것입니다.

111 davcar Jan 02 2009 at 22:29

확인하려는 이메일 주소는 System.Net.Mail네임 스페이스를 사용하는 ASP.NET 웹 응용 프로그램 에서 사용자 목록에 이메일을 보내는 데 사용됩니다 .

따라서 매우 복잡한 정규식을 사용하는 대신 MailAddress주소에서 인스턴스 를 만들려고 합니다. MailAddress주소가 제대로 형성되지 않은 경우 생성자는 예외가 발생합니다. 이런 식으로 적어도 이메일을 문 밖으로 가져올 수 있다는 것을 알고 있습니다. 물론 이것은 서버 측 유효성 검사이지만 최소한 어쨌든 필요합니다.

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;
    }
}
110 Rinke Dec 29 2012 at 04:07

빠른 답변

입력 유효성 검사에 다음 정규식을 사용하십시오.

([-!#-'*+/-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])?)+

이 정규식과 일치하는 주소 :

  • RFC 5321/5322를 엄격하게 준수하는 로컬 부품 (예 : @ 기호 앞의 부품)이 있어야합니다.
  • 적어도 두 개의 레이블이있는 호스트 이름 인 도메인 부분 (즉, @ 기호 뒤의 부분)이 있으며 각 레이블은 최대 63 자입니다.

두 번째 제약은 RFC 5321/5322에 대한 제한입니다.

정교한 답변

전자 메일 주소를 인식하는 정규식을 사용하면 문서에서 전자 메일 주소를 검색하거나 사용자 입력을 확인하거나 데이터 저장소에 대한 무결성 제약 조건과 같은 다양한 상황에서 유용 할 수 있습니다.

그러나 주소가 실제로 기존 사서함을 참조하는지 확인하려는 경우 주소로 메시지를 보내는 대신 사용할 수 없다는 점에 유의해야합니다. 주소가 문법적으로 올바른지 확인하려는 경우 정규식을 사용할 수 있지만 ""@[]확실히 기존 사서함을 참조하지 않는 문법적으로 올바른 전자 메일 주소입니다.

이메일 주소의 구문은 다양한 RFC , 특히 RFC 822 및 RFC 5322 에서 정의되었습니다 . RFC 822는 "원본"표준으로, RFC 5322는 최신 표준으로 간주되어야합니다. RFC 822에 정의 된 구문은 가장 관대하며 후속 표준은 구문을 더욱 제한하여 새로운 시스템이나 서비스가 구식 구문을 인식해야하지만 절대 생성하지 않습니다.

이 대답에 나는 의미하는 "이메일 주소"를 할게요 addr-specRFC의 정의 (예로서 [email protected],하지만 "John Doe"<[email protected]>,도 some-group:[email protected],[email protected];).

RFC 구문을 정규식으로 변환하는 데 한 가지 문제가 있습니다. 구문이 규칙적이지 않습니다! 이는 무한 중첩이 가능한 이메일 주소의 선택적 주석을 허용하는 반면 무한 중첩은 정규 표현식으로 설명 할 수 없기 때문입니다. 주석이 포함 된 주소를 검색하거나 유효성을 검사하려면 파서 또는 더 강력한식이 필요합니다. (Perl과 같은 언어에는 정규식과 같은 방식으로 문맥 자유 문법을 설명하는 구조가 있습니다.)이 답변에서는 주석을 무시하고 적절한 정규식 만 고려합니다.

RFC는 이메일 주소가 아닌 이메일 메시지에 대한 구문을 정의합니다. 주소는 다양한 헤더 필드에 나타날 수 있으며 여기에서 주로 정의됩니다. 헤더 필드에 나타날 때 주소에는 공백, 주석 및 줄 바꿈이 포함될 수 있습니다 (어휘 토큰 사이). 그러나 의미 상 이것은 의미가 없습니다. 주소에서이 공백 등을 제거하면 의미 상 동등한 표준 표현 을 얻을 수 있습니다. 따라서의 표준 표현은 first. last (comment) @ [3.5.7.9]입니다 first.last@[3.5.7.9].

다른 목적을 위해 다른 구문을 사용해야합니다. 매우 오래된 문서에서 전자 메일 주소를 검색하려면 RFC 822에 정의 된 구문을 사용하는 것이 좋습니다. 반면에 사용자 입력을 확인하려면 다음을 사용할 수 있습니다. RFC 5322에 정의 된 구문으로, 아마도 표준 표현 만 허용합니다. 특정 사례에 적용 할 구문을 결정해야합니다.

ASCII 호환 문자 집합을 가정하여이 답변에서 POSIX "확장"정규식을 사용합니다.

RFC 822

다음 정규식에 도달했습니다. 나는 모든 사람들이 그것을 시도하고 깨도록 초대합니다. 오탐 또는 오탐을 발견 한 경우 댓글로 게시 해 주시면 최대한 빨리 수정하겠습니다.

([^][()<>@,;:\\". \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 822를 완전히 준수한다고 생각합니다 . 표준 형식의 이메일 주소 만 인식합니다. 공백을 인식 (접기)하는 정규식에 대해서는 아래 파생을 참조하십시오.

파생은 내가 어떻게 표현에 도달했는지 보여줍니다. RFC의 모든 관련 문법 규칙을 표시되는 그대로 나열하고 그 뒤에 해당하는 정규식을 나열합니다. 정오표가 게시 된 경우 수정 된 문법 규칙 ( "정오표"로 표시)에 대해 별도의 표현식을 제공하고 업데이트 된 버전을 후속 정규 표현식의 하위 표현식으로 사용합니다.

3.1.4 절에 명시된 바와 같이. RFC 822의 선택적 선형 공백이 어휘 토큰 사이에 삽입 될 수 있습니다. 해당되는 경우이 규칙을 수용하기 위해 표현식을 확장하고 결과를 "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

다음 정규식에 도달했습니다. 나는 모든 사람들이 그것을 시도하고 깨도록 초대합니다. 오탐 또는 오탐을 발견 한 경우 댓글로 게시 해 주시면 최대한 빨리 수정하겠습니다.

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

정오표를 포함하여 RFC 5322를 완전히 준수한다고 생각합니다 . 표준 형식의 이메일 주소 만 인식합니다. 공백을 인식 (접기)하는 정규식에 대해서는 아래 파생을 참조하십시오.

파생은 내가 어떻게 표현에 도달했는지 보여줍니다. RFC의 모든 관련 문법 규칙을 표시되는 그대로 나열하고 그 뒤에 해당하는 정규식을 나열합니다. 의미 상 무관 한 (접는) 공백을 포함하는 규칙의 경우이 공백을 허용하지 않는 "(normalized)"로 표시된 별도의 정규식을 제공합니다.

RFC의 모든 "obs-"규칙을 무시했습니다. 이는 정규식이 RFC 5322를 엄격하게 준수하는 이메일 주소와 만 일치 함을 의미합니다. "오래된"주소와 일치해야하는 경우 ( "obs-"규칙을 포함하는 느슨한 문법이 수행하는 것처럼) 이전 단락의 RFC 822 정규식 중 하나를 사용할 수 있습니다.

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^-~]*])

일부 소스 (특히 w3c )는 RFC 5322가 로컬 부분 (예 : @ 기호 앞의 부분)에서 너무 엄격하다고 주장합니다. "..", "a..b"및 "a"때문입니다. 있다 없다 가 사서함 이름으로 사용할 수 있지만, 유효 도트 원자. 은 RFC 그러나 않습니다 그들이 인용하는 경우를 제외 해,이 같은 지역 부품 수 있습니다. 그래서 대신에 의미 상 동등한을 [email protected]작성해야합니다 "a..b"@example.net.

추가 제한

SMTP ( RFC 5321에 정의 됨 )는 유효한 이메일 주소 세트 (또는 실제로는 사서함 이름)를 추가로 제한합니다. 일치하는 이메일 주소가 실제로 이메일을 보내는 데 사용될 수 있도록 더 엄격한 문법을 ​​적용하는 것이 합리적입니다.

RFC 5321은 기본적으로 "로컬"부분 (예 : @-기호 앞의 부분) 만 남기지 만 도메인 부분 (예 : @-기호 뒤의 부분)에서는 더 엄격합니다. 도트 원자 대신 호스트 이름 만 허용하고 도메인 리터럴 대신 주소 리터럴 만 허용합니다.

RFC 5321에 제시된 문법은 호스트 이름과 IP 주소 모두에 대해 너무 관대합니다. 이 초안 과 RFC 1034 를 지침으로 사용하여 문제의 규칙을 "수정"할 자유를 얻었습니다 . 결과 정규식은 다음과 같습니다.

([-!#-'*+/-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^-~]+)])

사용 사례에 따라 정규식에서 "General-address-literal"을 허용하지 않을 수도 있습니다. 또한 (?!IPv6:)"General-address-literal"부분이 잘못된 IPv6 주소와 일치하는 것을 방지하기 위해 최종 정규식에서 부정적인 예견 을 사용했습니다 . 일부 정규식 프로세서는 부정적인 예측을 지원하지 않습니다. |(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+전체 "General-address-literal"부분을 제거하려면 정규식 에서 하위 문자열 을 제거하십시오 .

파생은 다음과 같습니다.

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^-~]+)])

사용자 입력 유효성 검사

일반적인 사용 사례는 예를 들어 html 양식에서 사용자 입력 유효성 검사입니다. 이 경우 일반적으로 주소 리터럴을 제외하고 호스트 이름에 두 개 이상의 레이블을 요구하는 것이 합리적입니다. 이전 섹션의 개선 된 RFC 5321 정규식을 기준으로하면 결과 표현식은 다음과 같습니다.

([-!#-'*+/-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..b"@example.net또는 심지어 "a b"@example.net)를 알 수 없기 때문에 따옴표로 묶인 문자열을 배제하는 등 로컬 부분을 더 제한하지 않는 것이 좋습니다 .

또한 리터럴 최상위 도메인 목록에 대해 명시 적으로 유효성을 검사하거나 길이 제약을 부과하는 것도 권장하지 않습니다 ( ".museum"이 무효화되는 방법을 기억하십시오 [a-z]{2,4}).하지만 다음을 수행해야합니다.

([-!#-'*+/-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|기타...)

명시 적 최상위 도메인 유효성 검사 경로를 따르기로 결정한 경우 정규식을 최신 상태로 유지하십시오.

추가 고려 사항

도메인 부분 (@-기호 뒤)에서 호스트 이름 만 허용하는 경우 위의 정규식은 최대 63 자까지의 레이블 만 허용합니다. 그러나 전체 호스트 이름이 최대 253 자 (점 포함) 여야한다는 사실을 강요하지 않습니다. 이 제약은 엄격하게 말하면 여전히 규칙적이지만이 규칙을 통합하는 정규식을 만드는 것은 불가능합니다.

특히 입력 유효성 검사를 위해 정규식을 사용할 때 고려해야 할 또 다른 사항은 사용자에 대한 피드백입니다. 사용자가 잘못된 주소를 입력하면 단순한 "구문 적으로 잘못된 주소"보다 약간 더 많은 피드백을 제공하는 것이 좋습니다. "바닐라"정규식으로는 불가능합니다.

이 두 가지 고려 사항은 주소를 구문 분석하여 해결할 수 있습니다. 호스트 이름에 대한 추가 길이 제한은 경우에 따라이를 검사하는 추가 정규식을 사용하고 주소를 두 식에 대해 일치시킴으로써 해결 될 수도 있습니다.

이 답변의 어떤 정규식도 성능에 최적화되지 않았습니다. 성능이 문제인 경우 선택한 정규식을 최적화 할 수 있는지 (그리고 방법) 확인해야합니다.

73 Draemon Oct 14 2008 at 21:18

이에 대한 많은 예가 인터넷에 나와 있습니다 (그리고 RFC를 완전히 검증하는 사례도 있다고 생각합니다.하지만 메모리가 제공되는 경우 수십 / 수백 줄 길이입니다). 사람들은 이런 종류의 것을 확인하는 데 몰두하는 경향이 있습니다. 왜 @와 적어도 하나가 있는지 확인하십시오. 간단한 최소 길이를 충족합니다. 가짜 이메일을 입력하고 어쨌든 유효한 정규식과 일치하는 것은 간단합니다. 거짓 양성이 거짓 음성보다 낫다고 생각합니다.

65 DOK Oct 14 2008 at 23:19

허용되는 문자를 결정할 때 아 포스트 로프 및 하이픈으로 연결된 친구를 기억하십시오. 회사에서 HR 시스템에서 내 이름을 사용하여 내 이메일 주소를 생성한다는 사실을 제어 할 수 없습니다. 그것은 내성에 아포스트로피를 포함합니다. 내 이메일 주소가 "유효하지 않음"이라는 사실로 인해 웹 사이트와 상호 작용하지 못하도록 차단 된 횟수를 알 수 없습니다.

62 EvanCarroll Jan 27 2010 at 23:43

이 정규식은 Perl의 Email :: Valid 라이브러리 에서 가져온 것 입니다. 저는 이것이 가장 정확하다고 믿습니다. 모든 822와 일치합니다. 그리고 이것은 O'Reilly 책의 정규 표현식을 기반으로합니다.

Mastering Regular Expressions 에서 Jeffrey Friedl의 예제를 사용하여 빌드 된 정규식 (http://www.ora.com/catalog/regexp/).

$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
46 SimonSimCity Dec 21 2011 at 15:40

PHP로 작성하는 동안 이메일에 PHP 내장 유효성 검사를 사용하는 것이 좋습니다.

filter_var($value, FILTER_VALIDATE_EMAIL)

5.3.6보다 낮은 php 버전을 실행하는 경우 다음 문제에 유의하십시오. https://bugs.php.net/bug.php?id=53091

이 내장 유효성 검사가 작동하는 방법에 대한 자세한 내용은 여기를 참조하십시오. PHP의 filter_var FILTER_VALIDATE_EMAIL이 실제로 작동합니까?

43 adnam Oct 14 2008 at 23:35

Cal Henderson (Flickr)은 PHP에서 이메일 주소 구문 분석 이라는 기사를 작성했으며 적절한 RFC (2) 822 준수 이메일 주소 구문 분석을 수행하는 방법을 보여줍니다. cc 라이센스 가 있는 php , python 및 ruby로 소스 코드를 얻을 수도 있습니다 .

42 Kon Oct 14 2008 at 21:23

다른 사람이 이미 더 나은 버전을 만들었을 가능성이 있기 때문에 내 자신의 정규 표현식으로 작성하는 데 전혀 신경 쓰지 않습니다. 나는 항상 regexlib 를 사용하여 원하는 것을 찾습니다.

37 PhiLho Oct 14 2008 at 22:38

정말로 사용할 수있는 것은 없습니다. 이메일 주소 확인을위한 PHP 라이브러리가 있습니까?에 대한 답변
에서 몇 가지 문제에 대해 논의 합니다. , Regexp 에서도 이메일 주소 인식이 어렵습니까?

요컨대, 사용 가능한 단일 정규식이 적절한 작업을 수행 할 것이라고 기대하지 마십시오. 그리고 가장 좋은 정규식은 전자 메일의 유효성이 아닌 구문의 유효성을 검사합니다 ([email protected]은 정확하지만 아마도 반송 될 것입니다 ...).

36 spig Oct 23 2009 at 04:54

적어도 유효한 이메일 주소를 거부하지 않는 간단한 정규 표현식은 무언가를 확인한 다음 @ 기호가 뒤 따르고 마침표와 적어도 2 개가 뒤 따르는 것입니다. 아무것도 거부하지 않지만 사양을 검토 한 후 유효하고 거부 할 이메일을 찾을 수 없습니다.

이메일 = ~ /.+@[^@]+\.[^@]{2,}$/

29 chaos May 24 2009 at 01:22

jQuery Validation 플러그인에서 사용하는 것을 사용할 수 있습니다.

/^((([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
25 EricSchoonover May 29 2010 at 05:03

이메일 주소 확인을위한 최상의 정규 표현식에 대한 가장 포괄적 인 평가는이 링크를 참조하십시오. " 정규 표현식을 검증하는 이메일 주소 비교 "

다음은 참조 용으로 현재 최상위 표현식입니다.

/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([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
23 BalusC Dec 19 2009 at 06:40

비 라틴어 (중국어, 아랍어, 그리스어, 히브리어, 키릴 문자 등) 도메인 이름은 조만간 허용 될 예정 입니다. 이러한 문자가 적용되는 확실하지 않기 때문에 모든 사람은 사용하는 이메일 정규식을 변경할 수있다 [a-z]/i\w. 그들은 모두 실패 할 것입니다.

결국 이메일 주소를 확인 하는 가장 좋은 방법은 실제로 해당 주소로 이메일을 보내 주소를 확인하는 것입니다. 이메일 주소가 사용자 인증 (등록 / 로그인 등)의 일부인 경우이를 사용자 활성화 시스템과 완벽하게 결합 할 수 있습니다. 즉, 고유 한 활성화 키가있는 링크가있는 이메일을 지정된 이메일 주소로 보내고 사용자가 이메일의 링크를 사용하여 새로 생성 된 계정을 활성화 한 경우에만 로그인을 허용합니다.

정규식의 목적이 UI에서 사용자에게 지정된 이메일 주소가 올바른 형식이 아니라는 것을 신속하게 알리는 것이라면 기본적으로 다음 정규식과 일치하는지 확인하는 것이 가장 좋습니다.

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

그렇게 간단합니다. 도대체 왜 이름과 도메인에 사용되는 문자에 관심이 있습니까? 서버가 아닌 유효한 이메일 주소를 입력하는 것은 클라이언트의 책임입니다. 클라이언트가와 같이 구문 상 유효한 이메일 주소를 입력하더라도 [email protected]이것이 합법적 인 이메일 주소임을 보장하지는 않습니다. 어느 정규식도 그것을 다룰 수 없습니다.

20 RossAllan Aug 14 2015 at 19:30

HTML5 스펙은 제안 이메일 주소를 검증하기위한 간단한 정규식 :

/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[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])?)*$/

이것은 의도적으로 RFC 5322를 준수하지 않습니다 .

참고 : 이 요구 사항은 RFC 5322 의 고의적 위반 으로 , 동시에 너무 엄격 ( 문자 앞 ), 너무 모호 ( 문자 뒤 ), 너무 느슨 (주석, 공백 문자 허용, 그리고 대부분의 사용자에게 익숙하지 않은 방식으로 인용 된 문자열)은 여기서 실용적입니다.@@

전체 길이는 RFC 3696 에라타 1690에 따라 254 자로 제한 될 수도 있습니다 .

16 GregBacon Jun 25 2009 at 22:15

생생한 데모를 위해 다음 괴물은 꽤 훌륭하지만 구문 적으로 유효한 모든 이메일 주소를 올바르게 인식하지 못합니다. 중첩 된 댓글을 최대 4 단계까지 인식합니다.

이것은 파서의 작업이지만 주소가 구문 상 유효하더라도 여전히 전달되지 않을 수 있습니다. 때때로 당신은 "이봐, 너희들, 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); 
12 AZ_ Dec 29 2010 at 19:58

공식 표준 RFC 2822 에 따르면 유효한 이메일 정규식은

(?:[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])+)\])

Java에서 사용하고 싶다면 정말 쉽습니다.

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 Mac Jul 20 2011 at 10:37

여기 내가 사용하는 PHP가 있습니다. 나는 여기에 다른 주석가가 선언 한 "거짓 긍정이 거짓 부정보다 낫다"라는 정신으로이 솔루션을 선택했으며 응답 시간을 유지하고 서버 부하를 낮추는 것과 관련하여 서버 리소스를 낭비 할 필요가 없습니다. 가장 간단한 사용자 오류를 제거하는 정규식입니다. 원하는 경우 언제든지 테스트 이메일을 보내서 후속 조치를 취할 수 있습니다.

function validateEmail($email) { return (bool) stripos($email,'@');
}
11 MichaelRushton Nov 20 2009 at 23:05

RFC 5322 표준 :

점 원자 로컬 부분, 인용 문자열 로컬 부분, 사용되지 않는 (점 원자 및 인용 문자열 혼합) 로컬 부분, 도메인 이름 도메인, (IPv4, IPv6 및 IPv4 매핑 IPv6 주소) 도메인 리터럴 도메인, 및 (중첩 된) 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'

RFC 5321 표준 :

도트 아톰 로컬 부분, 인용 문자열 로컬 부분, 도메인 이름 도메인 및 (IPv4, IPv6 및 IPv4 매핑 된 IPv6 주소) 도메인 리터럴 도메인을 허용합니다.

'/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!"?(?>\\\[ -~]|[^"]){65,}"?@)(?>([!#-\'*+\/-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'

기본:

도트 아톰 로컬 부분 및 도메인 이름 도메인을 허용합니다 (TLD가 2-6 개의 알파벳 문자로 제한되는 도메인 이름 레이블이 2 개 이상 필요).

"/^(?!.{255,})(?!.{65,}@)([!#-'*+\/-9=?^-~-]+)(?>\.(?1))*@(?!.*[^.]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?\.){1,126}[a-z]{2,6}$/iD"
8 TombMedia Dec 02 2012 at 13:15

나는 잠시 동안이 수정 된 버전의 정규식을 사용해 왔으며 너무 많은 놀라움을 남기지 않았습니다. 나는 아직 이메일에서 아포스트로피를 본 적이 없으므로 유효성을 검사하지 않습니다 . 그것은 유효성을 수행 Jean+Franç[email protected]하고 试@例子.测试.مثال.آزمایشی그 이외의 영숫자 문자가 아닌 이상 학대를 [email protected].

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

IP 주소를 지원 [email protected]하지만 .NET과 같은 가짜 IP 범위를 처리하기에 충분하지 않습니다 999.999.999.1.

또한 [email protected]원본이 통과했다고 생각하는 3 자 이상의 모든 TLD를 지원합니다 . 나는 이겼습니다. 이제 3 자 이상의 tld가 너무 많습니다.

나는 acrosman이 그의 정규식을 포기했다는 것을 알고 있지만이 풍미는 계속 살아 있습니다.

8 Prasad Apr 28 2012 at 16:45

빈 값 (잘못된 이메일이 아님)을 받아도 괜찮고 PHP 5.2 이상을 실행중인 경우 다음을 제안합니다.

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