จะตรวจสอบที่อยู่อีเมลโดยใช้นิพจน์ทั่วไปได้อย่างไร?

Oct 14 2008

ในช่วงหลายปีที่ผ่านมาฉันได้พัฒนานิพจน์ทั่วไปอย่างช้าๆที่ตรวจสอบที่อยู่อีเมล MOST อย่างถูกต้องโดยสมมติว่าพวกเขาไม่ได้ใช้ที่อยู่ IP เป็นส่วนของเซิร์ฟเวอร์

ฉันใช้มันในโปรแกรม PHP หลายตัวและทำงานได้เกือบตลอดเวลา อย่างไรก็ตามในบางครั้งฉันได้รับการติดต่อจากใครบางคนที่มีปัญหากับไซต์ที่ใช้ไซต์นี้และสุดท้ายฉันก็ต้องทำการปรับเปลี่ยนบางอย่าง (ล่าสุดฉันรู้ว่าฉันไม่อนุญาตให้ใช้ TLD 4 ตัวอักษร)

นิพจน์ทั่วไปที่ดีที่สุดที่คุณมีหรือเคยเห็นในการตรวจสอบความถูกต้องของอีเมลคืออะไร?

ฉันเคยเห็นวิธีแก้ปัญหาหลายอย่างที่ใช้ฟังก์ชันที่ใช้นิพจน์สั้น ๆ หลายอย่าง แต่ฉันอยากจะมีนิพจน์ที่ซับซ้อนแบบยาวหนึ่งนิพจน์ในฟังก์ชันง่ายๆแทนที่จะเป็นนิพจน์สั้น ๆ หลาย ๆ นิพจน์ในฟังก์ชันที่ซับซ้อนกว่านี้

คำตอบ

2561 bortzmeyer Oct 14 2008 at 21:26

อย่างเต็มที่ RFC 822 regex ตามมาตรฐานจะไม่มีประสิทธิภาพและปิดบังเพราะความยาวของมัน โชคดีที่ RFC 822 ถูกแทนที่สองครั้งและสเปคปัจจุบันที่อยู่อีเมลเป็นRFC 5322 RFC 5322 นำไปสู่ ​​regex ที่สามารถเข้าใจได้หากศึกษาเพียงไม่กี่นาทีและมีประสิทธิภาพเพียงพอสำหรับการใช้งานจริง

regex ที่สอดคล้องกับ RFC 5322 หนึ่งรายการสามารถพบได้ที่ด้านบนของเพจที่ http://emailregex.com/แต่ใช้รูปแบบที่อยู่ IP ที่ลอยอยู่ทั่วอินเทอร์เน็ตโดยมีจุดบกพร่องที่อนุญาตให้00มีค่าทศนิยมของไบต์ที่ไม่ได้ลงชื่อใด ๆ ในที่อยู่ที่คั่นด้วยจุดซึ่งผิดกฎหมาย ส่วนที่เหลือดูเหมือนจะสอดคล้องกับไวยากรณ์ RFC 5322 และผ่านการทดสอบหลายอย่างโดยใช้grep -Poรวมถึงกรณีชื่อโดเมนที่อยู่ IP ชื่อที่ไม่ถูกต้องและชื่อบัญชีที่มีและไม่มีเครื่องหมายอัญประกาศ

การแก้ไข00ข้อบกพร่องในรูปแบบ IP เราได้รับ regex ที่ใช้งานได้และค่อนข้างเร็ว (ขูดเวอร์ชันที่แสดงผลไม่ใช่มาร์กดาวน์สำหรับโค้ดจริง)

(?: [ก-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 (ห้องสมุด regex ใช้เช่นใน PHP) สามารถRFC แยกอย่างถูกต้อง 5322 โดยไม่ต้องผูกปม Python และ C # สามารถทำได้เช่นกัน แต่ใช้ไวยากรณ์ที่แตกต่างจากสองตัวแรก อย่างไรก็ตามหากคุณถูกบังคับให้ใช้ภาษาการจับคู่รูปแบบที่มีประสิทธิภาพน้อยกว่าภาษาใดภาษาหนึ่งคุณควรใช้โปรแกรมแยกวิเคราะห์จริง

สิ่งสำคัญคือต้องเข้าใจด้วยว่าการตรวจสอบความถูกต้องตาม RFC จะไม่บอกอะไรเลยว่าที่อยู่นั้นมีอยู่จริงในโดเมนที่ให้มาหรือไม่หรือบุคคลที่ป้อนที่อยู่นั้นเป็นเจ้าของที่แท้จริง ผู้อื่นลงชื่อสมัครรับรายชื่ออีเมลด้วยวิธีนี้ตลอดเวลา การแก้ไขที่ต้องใช้การตรวจสอบความถูกต้องแบบเพ้อฝันซึ่งเกี่ยวข้องกับการส่งข้อความที่มีโทเค็นการยืนยันที่จะป้อนในหน้าเว็บเดียวกับที่อยู่

โทเค็นการยืนยันเป็นวิธีเดียวที่จะรู้ว่าคุณมีที่อยู่ของบุคคลที่ป้อนข้อมูล นี่คือเหตุผลที่ตอนนี้รายชื่ออีเมลส่วนใหญ่ใช้กลไกดังกล่าวเพื่อยืนยันการลงชื่อสมัครใช้ [email protected]ท้ายที่สุดใคร ๆ ก็สามารถวางลงได้และนั่นจะเป็นการแยกวิเคราะห์ว่าเป็นกฎหมาย แต่ก็ไม่น่าจะใช่คนอื่น

สำหรับ PHP คุณไม่ควรใช้รูปแบบที่กำหนดในการตรวจสอบที่อยู่อีเมลด้วย PHP ซึ่งเป็นวิธีที่ถูกต้องจากที่ฉันอ้างถึง:

มีอันตรายบางประการที่การใช้งานทั่วไปและการเข้ารหัสที่แพร่หลายอย่างกว้างขวางจะสร้างมาตรฐานโดยพฤตินัยสำหรับที่อยู่อีเมลที่มีข้อ จำกัด มากกว่ามาตรฐานทางการที่บันทึกไว้

นั่นไม่ดีไปกว่ารูปแบบอื่น ๆ ที่ไม่ใช่ RFC มันไม่ฉลาดพอที่จะจัดการแม้แต่RFC 822นับประสาอะไรกับ RFC 5322 อันนี้ก็คือ

หากคุณต้องการที่จะได้รับแฟนซีและอวดความรู้การใช้เครื่องมือของรัฐที่สมบูรณ์ นิพจน์ทั่วไปสามารถทำหน้าที่เป็นตัวกรองพื้นฐานเท่านั้น ปัญหาเกี่ยวกับนิพจน์ทั่วไปคือการบอกใครบางคนว่าที่อยู่อีเมลที่ถูกต้องสมบูรณ์ของพวกเขาไม่ถูกต้อง (เป็นผลบวกที่ผิดพลาด) เนื่องจากนิพจน์ทั่วไปของคุณไม่สามารถจัดการได้เป็นเพียงการหยาบคายและไม่สุภาพจากมุมมองของผู้ใช้ กลไกของสถานะสำหรับวัตถุประสงค์สามารถตรวจสอบความถูกต้องและแก้ไขที่อยู่อีเมลที่อาจถูกพิจารณาว่าไม่ถูกต้องเนื่องจากแยกส่วนที่อยู่อีเมลตาม 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ระดับใช้ parser 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 เช่นกัน

หากคุณต้องการใช้ regex จริงๆนี่คือ :

(?: (?: \ 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)? [\ เสื้อ]) *) (?: \. (?: (?: \ 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+$/

แน่นอนว่าจะจับคู่สิ่งที่ไม่ใช่ที่อยู่อีเมลที่ถูกต้อง แต่เป็นเรื่องของการได้รับข้อผิดพลาดทั่วไป

มีการเปลี่ยนแปลงจำนวนมากที่สามารถทำได้กับ regex นั้น (และบางส่วนอยู่ในความคิดเห็นสำหรับคำตอบนี้) แต่มันง่ายและเข้าใจง่ายและเป็นความพยายามครั้งแรกที่ดี

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 ที่อยู่ทดสอบทั้งหมด ฉันทำการทดสอบเหล่านี้กับตัวตรวจสอบความถูกต้องฟรีทั้งหมดที่ฉันสามารถหาได้

ฉันจะพยายามอัปเดตหน้านี้อยู่เสมอเมื่อผู้คนปรับปรุงตัวตรวจสอบความถูกต้องของตน ขอบคุณแคลไมเคิลเดฟพอลและฟิลสำหรับความช่วยเหลือและความร่วมมือในการรวบรวมการทดสอบเหล่านี้และคำวิจารณ์เชิงสร้างสรรค์เกี่ยวกับตัวตรวจสอบความถูกต้องของฉันเอง

ผู้คนควรตระหนักถึงความผิดพลาดของ RFC 3696โดยเฉพาะ ตัวอย่างตามรูปแบบบัญญัติสามตัวอย่างเป็นที่อยู่ที่ไม่ถูกต้องในความเป็นจริง และความยาวสูงสุดของที่อยู่คือ 254 หรือ 256 อักขระไม่ใช่ 320

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+)*$

ซึ่งเป็นสิ่งที่ใช้ใน ASP.NET โดย RegularExpressionValidator

142 ChristianVestHansen Oct 14 2008 at 21:17

ไม่ทราบเกี่ยวกับที่ดีที่สุด แต่คนนี้เป็นอย่างน้อยที่ถูกต้องเป็นเวลานานเป็นที่อยู่ของพวกเขามีความคิดเห็นปล้นและถูกแทนที่ด้วยช่องว่าง

อย่างจริงจัง. คุณควรใช้ไลบรารีที่เขียนไว้แล้วเพื่อตรวจสอบความถูกต้องของอีเมล วิธีที่ดีที่สุดคือส่งอีเมลยืนยันไปยังที่อยู่นั้น

111 davcar Jan 02 2009 at 22:29

ที่อยู่อีเมลที่ฉันต้องการตรวจสอบจะถูกใช้โดยเว็บแอปพลิเคชัน ASP.NET โดยใช้System.Net.Mailเนมสเปซเพื่อส่งอีเมลไปยังรายชื่อบุคคล

ดังนั้นแทนที่จะใช้นิพจน์ทั่วไปที่ซับซ้อนมากฉันแค่พยายามสร้าง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

คำตอบที่รวดเร็ว

ใช้ regex ต่อไปนี้สำหรับการตรวจสอบอินพุต:

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

คำตอบอย่างละเอียด

การใช้นิพจน์ทั่วไปที่รับรู้ที่อยู่อีเมลอาจมีประโยชน์ในสถานการณ์ต่างๆเช่นเพื่อสแกนหาที่อยู่อีเมลในเอกสารเพื่อตรวจสอบความถูกต้องของข้อมูลที่ผู้ใช้ป้อนหรือเป็นข้อ จำกัด ด้านความสมบูรณ์ของที่เก็บข้อมูล

อย่างไรก็ตามควรสังเกตว่าหากคุณต้องการทราบว่าที่อยู่นั้นอ้างถึงกล่องจดหมายที่มีอยู่จริงหรือไม่ไม่มีสิ่งใดทดแทนการส่งข้อความไปยังที่อยู่นั้นได้ หากคุณต้องการตรวจสอบว่าที่อยู่นั้นถูกต้องตามหลักไวยากรณ์หรือไม่คุณสามารถใช้นิพจน์ทั่วไปได้ แต่โปรดทราบว่าที่""@[]อยู่อีเมลที่ถูกต้องตามหลักไวยากรณ์ซึ่งไม่ได้อ้างถึงกล่องจดหมายที่มีอยู่อย่างแน่นอน

ไวยากรณ์ของที่อยู่อีเมลที่ได้รับการกำหนดในหลายRFCsสะดุดตาที่สุดRFC 822และRFC 5322 RFC 822 ควรถูกมองว่าเป็นมาตรฐาน "ดั้งเดิม" และ RFC 5322 เป็นมาตรฐานล่าสุด ไวยากรณ์ที่กำหนดไว้ใน RFC 822 เป็นมาตรฐานที่ผ่อนปรนมากที่สุดและมาตรฐานที่ตามมาได้ จำกัด ไวยากรณ์เพิ่มเติมขึ้นเรื่อย ๆ โดยที่ระบบหรือบริการที่ใหม่กว่าควรรู้จักไวยากรณ์ที่ล้าสมัย แต่จะไม่สร้างขึ้น

ในคำตอบนี้ฉันจะใช้ "ที่อยู่อีเมล" หมายถึงaddr-specตามที่กำหนดไว้ใน RFCs (เช่น[email protected]แต่ไม่ใช่"John Doe"<[email protected]>หรือsome-group:[email protected],[email protected];)

มีปัญหาอย่างหนึ่งในการแปลไวยากรณ์ RFC เป็น regexes: ไวยากรณ์ไม่ปกติ! เนื่องจากอนุญาตให้แสดงความคิดเห็นเพิ่มเติมในที่อยู่อีเมลที่สามารถซ้อนกันได้ไม่ จำกัด ในขณะที่การซ้อนแบบไม่สิ้นสุดไม่สามารถอธิบายได้ด้วยนิพจน์ทั่วไป หากต้องการสแกนหรือตรวจสอบที่อยู่ที่มีความคิดเห็นคุณต้องมีตัวแยกวิเคราะห์หรือนิพจน์ที่มีประสิทธิภาพมากขึ้น (โปรดทราบว่าภาษาเช่น Perl มีโครงสร้างเพื่ออธิบายไวยากรณ์อิสระตามบริบทในลักษณะคล้ายนิพจน์ทั่วไป) ในคำตอบนี้ฉันจะไม่สนใจความคิดเห็นและพิจารณาเฉพาะนิพจน์ทั่วไปที่เหมาะสมเท่านั้น

RFCs กำหนดไวยากรณ์สำหรับข้อความอีเมลไม่ใช่สำหรับที่อยู่อีเมลเช่นนี้ ที่อยู่อาจปรากฏในช่องส่วนหัวต่างๆและเป็นที่ที่กำหนดไว้เป็นหลัก เมื่อปรากฏในที่อยู่ฟิลด์ส่วนหัวอาจมีช่องว่าง (ระหว่างโทเค็นศัพท์) ความคิดเห็นและแม้แต่การแตกบรรทัด อย่างไรก็ตามความหมายนี้ไม่มีความสำคัญ โดยการลบช่องว่างนี้และอื่น ๆ จากที่อยู่คุณจะได้รับความหมายเทียบเท่าตัวแทนที่ยอมรับ ดังนั้นการเป็นตัวแทนยอมรับคือfirst. last (comment) @ [3.5.7.9]first.last@[3.5.7.9]

ควรใช้ไวยากรณ์ที่แตกต่างกันเพื่อวัตถุประสงค์ที่แตกต่างกัน หากคุณต้องการสแกนหาที่อยู่อีเมลในเอกสาร (อาจเก่ามาก) คุณควรใช้ไวยากรณ์ตามที่กำหนดไว้ใน RFC 822 ในทางกลับกันหากคุณต้องการตรวจสอบความถูกต้องของข้อมูลที่ผู้ใช้ป้อนคุณอาจต้องการใช้ ไวยากรณ์ตามที่กำหนดไว้ใน RFC 5322 อาจยอมรับเฉพาะการแสดงตามรูปแบบบัญญัติเท่านั้น คุณควรตัดสินใจว่าไวยากรณ์ใดที่ใช้กับกรณีเฉพาะของคุณ

ฉันใช้นิพจน์ทั่วไป "ขยาย" ของ POSIX ในคำตอบนี้โดยถือว่าชุดอักขระที่เข้ากันได้กับ ASCII

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

ผมเชื่อว่ามัน complient อย่างเต็มที่กับ RFC 822 รวมทั้งคหบดี จดจำเฉพาะที่อยู่อีเมลในรูปแบบบัญญัติเท่านั้น สำหรับนิพจน์ทั่วไปที่รู้จักช่องว่าง (พับ) โปรดดูที่มาด้านล่าง

รากศัพท์แสดงให้เห็นว่าฉันมาถึงนิพจน์ได้อย่างไร ฉันแสดงรายการกฎไวยากรณ์ที่เกี่ยวข้องทั้งหมดจาก RFC ตามที่ปรากฏตามด้วย regex ที่เกี่ยวข้อง ในกรณีที่มีการเผยแพร่ข้อผิดพลาดฉันจะให้นิพจน์แยกต่างหากสำหรับกฎไวยากรณ์ที่ได้รับการแก้ไข (ทำเครื่องหมาย "erratum") และใช้เวอร์ชันที่อัปเดตเป็นนิพจน์ย่อยในนิพจน์ทั่วไปที่ตามมา

ตามที่ระบุไว้ในย่อหน้า 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^-~]*])

ผมเชื่อว่ามัน complient อย่างเต็มที่กับ RFC 5322 รวมทั้งคหบดี จดจำเฉพาะที่อยู่อีเมลในรูปแบบบัญญัติเท่านั้น สำหรับนิพจน์ทั่วไปที่รู้จักช่องว่าง (พับ) โปรดดูที่มาด้านล่าง

รากศัพท์แสดงให้เห็นว่าฉันมาถึงนิพจน์ได้อย่างไร ฉันแสดงรายการกฎไวยากรณ์ที่เกี่ยวข้องทั้งหมดจาก RFC ตามที่ปรากฏตามด้วย regex ที่เกี่ยวข้อง สำหรับกฎที่มีช่องว่าง (พับ) ที่ไม่เกี่ยวข้องกับความหมายฉันจะให้ regex แยกต่างหากที่มีเครื่องหมาย "(normalized)" ซึ่งไม่ยอมรับช่องว่างนี้

ฉันไม่สนใจกฎ "obs-" ทั้งหมดจาก RFC ซึ่งหมายความว่า regexes จะจับคู่เฉพาะที่อยู่อีเมลที่สอดคล้องกับ RFC 5322 อย่างเคร่งครัด หากคุณต้องจับคู่ที่อยู่ "เก่า" (เช่นเดียวกับไวยากรณ์ที่หลวมกว่ารวมถึงกฎ "obs-" ด้วย) คุณสามารถใช้ regexes 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 จะทิ้งส่วน "local" ไว้เพียงอย่างเดียว (เช่นส่วนที่อยู่ก่อนหน้า @ -sign) แต่จะเข้มงวดกว่าในส่วนของโดเมน (เช่นส่วนที่อยู่หลัง @ -sign) อนุญาตให้ใช้เฉพาะชื่อโฮสต์แทนดอทอะตอมและแอดเดรสลิเทอรัลแทนลิเทอรัลของโดเมน

ไวยากรณ์ที่นำเสนอใน RFC 5321 นั้นผ่อนปรนมากเกินไปเมื่อพูดถึงทั้งชื่อโฮสต์และที่อยู่ IP ฉันใช้เสรีภาพในการ "แก้ไข" กฎที่เป็นปัญหาโดยใช้แบบร่างนี้และRFC 1034เป็นแนวทาง นี่คือผลลัพธ์ของ regex

([-!#-'*+/-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" ใน regex ของคุณทั้งนี้ขึ้นอยู่กับกรณีการใช้งาน โปรดทราบว่าฉันใช้การมองเชิงลบ(?!IPv6:)ใน regex สุดท้ายเพื่อป้องกันไม่ให้ส่วน "General-address-literal" ตรงกับที่อยู่ IPv6 ที่มีรูปแบบไม่ถูกต้อง โปรเซสเซอร์ regex บางตัวไม่รองรับการมองในแง่ลบ ลบสตริงย่อย|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+ออกจาก regex หากคุณต้องการนำส่วน "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 ในกรณีนี้มักจะมีเหตุผลที่จะยกเว้น address-literals และจำเป็นต้องมีป้ายกำกับอย่างน้อยสองป้ายในชื่อโฮสต์ การใช้ RFC 5321 regex ที่ปรับปรุงแล้วจากส่วนก่อนหน้าเป็นพื้นฐานนิพจน์ที่ได้จะเป็น:

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

ตรวจสอบให้แน่ใจว่า regex ของคุณเป็นปัจจุบันอยู่เสมอหากคุณตัดสินใจที่จะดำเนินการตามเส้นทางของการตรวจสอบโดเมนระดับบนสุดอย่างชัดเจน

ข้อควรพิจารณาเพิ่มเติม

เมื่อยอมรับเฉพาะชื่อโฮสต์ในส่วนของโดเมน (หลังเครื่องหมาย @) regex ด้านบนจะยอมรับเฉพาะป้ายกำกับที่มีอักขระไม่เกิน 63 ตัวเท่าที่ควร อย่างไรก็ตามพวกเขาไม่ได้บังคับว่าชื่อโฮสต์ทั้งหมดต้องมีความยาวไม่เกิน 253 อักขระ (รวมถึงจุดด้วย) แม้ว่าข้อ จำกัด นี้จะพูดอย่างเคร่งครัด แต่ยังคงเป็นปกติ แต่ก็เป็นไปไม่ได้ที่จะสร้าง regex ที่รวมกฎนี้ไว้

ข้อควรพิจารณาอีกประการหนึ่งโดยเฉพาะอย่างยิ่งเมื่อใช้ regexes สำหรับการตรวจสอบอินพุตคือการตอบกลับไปยังผู้ใช้ หากผู้ใช้ป้อนที่อยู่ไม่ถูกต้องก็จะเป็นการดีที่จะให้คำติชมมากกว่า "ที่อยู่ที่ไม่ถูกต้องทางไวยากรณ์" แบบธรรมดา ด้วย regexes "วานิลลา" สิ่งนี้เป็นไปไม่ได้

ข้อควรพิจารณาทั้งสองนี้สามารถแก้ไขได้โดยการแยกวิเคราะห์ที่อยู่ ข้อ จำกัด ด้านความยาวพิเศษของชื่อโฮสต์ในบางกรณีอาจแก้ไขได้โดยใช้ regex พิเศษที่ตรวจสอบและจับคู่ที่อยู่กับทั้งสองนิพจน์

ไม่มี regexes ใดในคำตอบนี้ที่ได้รับการปรับให้เหมาะสมกับประสิทธิภาพ หากประสิทธิภาพเป็นปัญหาคุณควรดูว่า (และอย่างไร) regex ที่คุณเลือกสามารถปรับให้เหมาะสมได้

73 Draemon Oct 14 2008 at 21:18

มีตัวอย่างมากมายในเน็ต (และฉันคิดว่าแม้แต่อันเดียวที่ตรวจสอบ RFC ได้อย่างสมบูรณ์ - แต่มันยาวหลายสิบ / หลายร้อยบรรทัดหากหน่วยความจำทำงาน) ผู้คนมักจะดำเนินการตรวจสอบความถูกต้องของสิ่งนี้ ทำไมไม่ตรวจสอบว่ามี @ และอย่างน้อยหนึ่ง และตรงตามความยาวขั้นต่ำที่เรียบง่าย การป้อนอีเมลปลอมเป็นเรื่องเล็กน้อยและยังคงตรงกับ regex ที่ถูกต้องอยู่ดี ฉันจะเดาว่าผลบวกลวงนั้นดีกว่าผลลบเท็จ

65 DOK Oct 14 2008 at 23:19

ในขณะที่ตัดสินใจว่าจะอนุญาตให้ใช้อักขระใดได้โปรดจำไว้ว่าเพื่อนที่มีเครื่องหมายวรรคตอนและยัติภังค์ของคุณ ฉันไม่สามารถควบคุมข้อเท็จจริงที่ว่า บริษัท ของฉันสร้างที่อยู่อีเมลของฉันโดยใช้ชื่อของฉันจากระบบ HR ซึ่งรวมถึงเครื่องหมายวรรคตอนในนามสกุลของฉันด้วย ฉันไม่สามารถบอกคุณได้ว่ากี่ครั้งแล้วที่ฉันถูกบล็อกไม่ให้โต้ตอบกับเว็บไซต์เนื่องจากที่อยู่อีเมลของฉัน "ไม่ถูกต้อง"

62 EvanCarroll Jan 27 2010 at 23:43

นิพจน์นี้มาจากอีเมลของ Perl ::ไลบรารีที่ถูกต้อง ฉันเชื่อว่ามันถูกต้องที่สุดมันตรงกับ 822 ทั้งหมดและมันขึ้นอยู่กับนิพจน์ทั่วไปในหนังสือ O'Reilly:

นิพจน์ทั่วไปที่สร้างขึ้นโดยใช้ตัวอย่างของ Jeffrey Friedl ในMastering Regular Expressions (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)

หากคุณใช้ php เวอร์ชันต่ำกว่า 5.3.6 โปรดระวังปัญหานี้: https://bugs.php.net/bug.php?id=53091

หากคุณต้องการข้อมูลเพิ่มเติมว่าการตรวจสอบความถูกต้องของ buid-in นี้ทำงานอย่างไรโปรดดูที่นี่: filter_var FILTER_VALIDATE_EMAIL ของ PHP ใช้งานได้จริงหรือไม่

43 adnam Oct 14 2008 at 23:35

Cal Henderson (Flickr) เขียนบทความชื่อParsing Email Adresses ใน PHPและแสดงวิธีการแยกวิเคราะห์ที่อยู่อีเมลที่สอดคล้องกับ RFC (2) 822 ที่เหมาะสม นอกจากนี้คุณยังจะได้รับรหัสที่มาในPHP , Python และทับทิมซึ่งเป็นซีซีได้รับใบอนุญาต

42 Kon Oct 14 2008 at 21:23

ฉันไม่เคยกังวลกับการสร้างด้วยนิพจน์ทั่วไปของตัวเองเพราะมีโอกาสที่จะมีคนอื่นมาพร้อมกับเวอร์ชันที่ดีกว่าแล้ว ฉันมักจะใช้regexlibเพื่อค้นหาสิ่งที่ฉันชอบ

37 PhiLho Oct 14 2008 at 22:38

ไม่มีอันที่ใช้งานได้จริง
ฉันพูดคุยเกี่ยวกับปัญหาบางอย่างในคำตอบของฉันมีไลบรารี php สำหรับการตรวจสอบที่อยู่อีเมลหรือไม่? ยังมีการพูดคุยกันในRegexp การรับรู้ที่อยู่อีเมลยาก?

ในระยะสั้นอย่าคาดหวังว่า regex เดียวที่ใช้งานได้จะทำงานได้อย่างเหมาะสม และ regex ที่ดีที่สุดจะตรวจสอบความถูกต้องของไวยากรณ์ไม่ใช่ความถูกต้องของอีเมล ([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

ไม่ต้องพูดถึงว่าชื่อโดเมนที่ไม่ใช่ภาษาละติน (จีนอาหรับกรีกฮิบรูซิริลลิกและอื่น ๆ ) จะได้รับอนุญาตในอนาคตอันใกล้นี้ ทุกคนมีการเปลี่ยนแปลง regex อีเมลที่ใช้เพราะตัวละครเหล่านั้นก็จะไม่ได้รับการคุ้มครองโดยมิได้[a-z]/i \wพวกเขาทั้งหมดจะล้มเหลว

ท้ายที่สุดวิธีที่ดีที่สุดในการตรวจสอบความถูกต้องของที่อยู่อีเมลคือการส่งอีเมลไปยังที่อยู่ดังกล่าวเพื่อตรวจสอบความถูกต้องของที่อยู่ หากที่อยู่อีเมลเป็นส่วนหนึ่งของการรับรองความถูกต้องของผู้ใช้ (ลงทะเบียน / เข้าสู่ระบบ / ฯลฯ ) คุณสามารถรวมเข้ากับระบบเปิดใช้งานผู้ใช้ได้อย่างสมบูรณ์แบบ คือส่งอีเมลพร้อมลิงก์ที่มีรหัสเปิดใช้งานเฉพาะไปยังที่อยู่อีเมลที่ระบุและอนุญาตให้เข้าสู่ระบบเมื่อผู้ใช้เปิดใช้งานบัญชีที่สร้างขึ้นใหม่โดยใช้ลิงก์ในอีเมลเท่านั้น

หากจุดประสงค์ของ regex เป็นเพียงเพื่อแจ้งให้ผู้ใช้ทราบอย่างรวดเร็วใน UI ว่าที่อยู่อีเมลที่ระบุไม่อยู่ในรูปแบบที่ถูกต้องควรตรวจสอบว่าตรงกับนิพจน์ทั่วไปต่อไปนี้หรือไม่:

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

ง่ายๆแค่นั้นเอง ทำไมคุณถึงสนใจอักขระที่ใช้ในชื่อและโดเมนบนโลกนี้? เป็นความรับผิดชอบของลูกค้าในการป้อนที่อยู่อีเมลที่ถูกต้องไม่ใช่ของเซิร์ฟเวอร์ แม้ว่าลูกค้าจะป้อนที่อยู่อีเมลที่ถูกต้องตามหลักไวยากรณ์เช่น[email protected]นี้ แต่ก็ไม่ได้รับประกันว่าเป็นที่อยู่อีเมลที่ถูกต้อง regex ไม่มีใครสามารถครอบคลุมสิ่งนั้นได้

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ซึ่งกำหนดไวยากรณ์สำหรับที่อยู่อีเมลที่เข้มงวดเกินไป (ก่อน@อักขระ) คลุมเครือเกินไป (หลัง@อักขระ) และหละหลวมเกินไป (อนุญาตให้แสดงความคิดเห็นอักขระเว้นวรรค และยกคำพูดในลักษณะที่ไม่คุ้นเคยสำหรับผู้ใช้ส่วนใหญ่) เพื่อใช้งานได้จริงที่นี่

ความยาวทั้งหมดอาจจะมีการ จำกัด 254 ตัวอักษรต่อRFC 3696 คหบดี 1690

16 GregBacon Jun 25 2009 at 22:15

สำหรับการสาธิตที่ชัดเจนสัตว์ประหลาดต่อไปนี้ค่อนข้างดี แต่ยังไม่สามารถจดจำที่อยู่อีเมลที่ถูกต้องตามหลักไวยากรณ์ทั้งหมดได้อย่างถูกต้อง: มันจดจำความคิดเห็นที่ซ้อนกันได้ลึกถึงสี่ระดับ

นี่เป็นงานสำหรับโปรแกรมแยกวิเคราะห์ แต่แม้ว่าที่อยู่จะถูกต้องตามหลักไวยากรณ์ แต่ก็ยังไม่สามารถส่งมอบได้ บางครั้งคุณต้องหันไปใช้วิธีคนบ้านนอก "เฮ้ทำดูพวกเรา!"

// 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 regex อีเมลที่ถูกต้องคือ

(?:[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:

อนุญาตให้ใช้ local-part dot-atom, quoted-string local-part, ล้าสมัย (ผสม dot-atom และ quoted-string) local-part, โดเมนเนมโดเมน, (IPv4, IPv6 และ IPv6 ที่แมป 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:

อนุญาตให้ใช้โดเมนลิเทอรัลของโดเมน dot-atom, สตริงที่อ้างถึงภายใน, โดเมนเนมโดเมนและ (IPv4, IPv6 และ IPv6 ที่แมป 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 ตัว)

"/^(?!.{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

ฉันใช้ regex เวอร์ชันสัมผัสนี้มาระยะหนึ่งแล้วและมันก็ไม่ได้ทำให้ฉันประหลาดใจมากเกินไป ฉันไม่เคยพบเครื่องหมายวรรคตอนในอีเมลดังนั้นจึงไม่สามารถตรวจสอบความถูกต้อง ได้ มันจะตรวจสอบJean+Franç[email protected]และแต่ไม่ล่วงละเมิดแปลกของตัวอักษรและตัวเลขเหล่านั้นไม่ใช่试@例子.测试.مثال.آزمایشی[email protected]

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

มันรองรับที่อยู่ IP [email protected]แต่ฉันไม่ได้ปรับแต่งให้เพียงพอที่จะจัดการกับช่วง IP ปลอมเช่น999.999.999.1.

นอกจากนี้ยังรองรับ TLD ทั้งหมดมากกว่า 3 อักขระซึ่งหยุด [email protected]ซึ่งฉันคิดว่าต้นฉบับปล่อยผ่าน ฉันเคยชนะมี tlds มากเกินไปตอนนี้เกิน 3 ตัวอักษร

ฉันรู้ว่า acrosman ละทิ้ง regex ของเขา แต่รสชาตินี้ยังคงอยู่

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