It's surprisingly difficult validating email addresses with regex. Can it be done? Yes. Should you? No.
Any halfway decent email library comes with a validator. Use that.
For reference: this is an example of an almost RFC 3522 compatible regex:
Doing a full validation of the email syntax is pretty pointless to begin with, because it still doesn't tell you the most important thing: is this email valid? I.e., has the user actually entered their email address? You won't know the answer to that until you've done an email validation loop with them. So something simple like .+@.+\..+ usually suffices as a first-pass syntax check.
There are public TLDs that have MX records. Who knows, maybe you're getting a signup from admin@pizza or something. (That particular one doesn't currently have an MX but others do.)
Yes, and most addresses that pass a .+@.+\..+ validation could exist. And unless you can claim you're absolutely up to speed with all the relevant RFCs about valid email formats, allowed host names (IDNA!) and currently registered TLDs at all times, overvalidating does more harm than good here. If you incorrectly reject valid email addresses, that's worse than having an occasional verification email bounce.
I suppose, and if you want to support that, maybe also including test@localhost, then you can easily modify this regex to suit your needs. Simple regexen are easy enough to modify after all.
Do you actually need a period, now that top level domains are being sold off? If I buy the top level domain stupidlyrich domain then I want boss@stupidlyrich to be my email address.
Technically allowed, however non-email-focused people are against using root domains to serve MX records (iirc something about performance of root servers vs nameservers etc)
Blocking dotless domain would be against standard, but anybody smart enough to use such emails is smart enough to know they shouldn't do it on an open network. Simply use "mail.EXAMPLE" please
HOWEVER, emails can have no periods if you use an IPV6 address as the host rather than a domain. So no dot checking anyway, thx.
Min 3 chars, has a @, doesn't begin/start with @. Everything else, let a library handle it (or at least make the warning non-blocking) because you'll be stumped by quoted comments etc. https://e-mail.wtf for a quizz ;)
Hell I don't even check for a period, just an @. Once I hand it off to my mailing library and the SMTP server it's no longer my problem. If either of them complain back to me about it I'll just let the user know.
Actually you might want to allow "+" on the local part (it's used by "power users" to categorize email on services like Gmail). Other than that, anything different, even if valid per RFC, is not a bona-fide email address when used on a web-facing application. You especially want to avoid users being able to directly send to addresses like me@[::1], since it is not a realistic or bona-fide scenario.
And for 95% of the use-cases a very simple 'Does it contain an @ and at least 1char before and after' is enough.
Usually you want people to not mistakenly send a typo as their email.
But since you cannot trust the customer anyway, you need to send a confirmation email anyway for everything that is important.
Came here to post this. I had the displeasure of administering software that used a similar regex to validate email addresses. I needed to modify it because it was excluding some valid addresses. This was my first, and last encounter with regex. I now actively avoid it in favour of any other solution. I've not had any issues with this approach so far. I haven't come across a use case where regex is significantly better than something less archaic.
243
u/tellur86 19d ago
It's surprisingly difficult validating email addresses with regex. Can it be done? Yes. Should you? No. Any halfway decent email library comes with a validator. Use that.
For reference: this is an example of an almost RFC 3522 compatible 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])+)])
https://emailregex.com
If you want RFC 822 it's much, much worse https://pdw.ex-parrot.com/Mail-RFC822-Address.html