I've created a general regex for this that validates and creates named captures of the full email, the user, and the domain.
Regex:
(?<email>(?<mailbox>(?:\w|[!#$%&'*+/=?^`{|}~-])+(?:\.(?:\w|[!#$%&'*+/=?^`{|}~-])+)*)@(?<full_domain>(?<subdomains>(?:(?:[^\W\d_](?:(?:[^\W_]|-)+[^\W_])?)\.)*)(?<root_domain>[^\W\d_](?:(?:[^\W_]|-)+[^\W_])?)\.(?<tld>[^\W\d_](?:(?:[^\W_]|-)+[^\W_])?)))
Explanation:
(?<email> # start Full Email capture
(?<mailbox> # Mailbox
(?:\w|[!#$%&'*+/=?^`{|}~-])+ # letter, number, underscore, or any of these special characters
(?: # Group: allow . in the middle of mailbox; can have multiple but can't be consecutive (no john..smith)
\. # match "."
(?:\w|[!#$%&'*+/=?^`{|}~-])+ # letter, number, underscore, or any of these special characters
)* # allow one letter mailboxes
) # close Mailbox capture
@ # match "@"
(?<full_domain> # Full Domain (including subdomains and tld)
(?<subdomains> # All Subdomains
(?: # label + '.' (so we can allow 0 or more)
(?: # label text
[^\W\d_] # start with a letter (\W is the inverse of \w so we end up with \w minus numbers and _)
(?: # paired with a ? to allow single letter domains
(?:[^\W_]|-)+ # allow letters, numbers, hyphens, but not underscore
[^\W_] # if domain is more than one character, it has to end with a letter or digit (not a hyphen or underscore)
)? # allow one letter sub domains
) # end label text
\.)* # allow 0 or more subdomains separated by '.'
) # close All Subdomains capture
(?<root_domain> # Root Domain
[^\W\d_] # start with a letter
(?: # paired with ? to make characters after the first optional
(?:[^\W_]|-)+ # allow letters, numbers, hyphens
[^\W_] # if domain is more than one character, it has to end with a letter or digit (not a hyphen or underscore)
)? # allow one letter domains
) # close Root Domain capture
\. # separator
(?<tld> # TLD
[^\W\d_] # start with a letter
(?: # paired with ? to make characters after the first optional
(?:[^\W_]|-)+ # allow letters, numbers, hyphens
[^\W_] # if domain is more than one character, it has to end with a letter or digit (not a hyphen)
)? # allow single letter tld
) # close TLD capture
) # close Full Domain capture
) # close Full Email capture
Notes
Generalized Regex: I've posted JUST the regex search itself not the php exclusive stuff. This is to make it easier to use for other people who find it based on the name "Regex Split Email Address".
Feature Compatibility: Not all regex processors support Named Captures, if you have trouble with it test it with your text on Regexr (checking the Details to see the captures). If it works there then double check if the regex engine you're using supports named captures.
Domain RFC: The domain part is also based on the domain RFC not just 2822
Dangerous Characters: I have explicitly included '$! etc to both make it clear these are allowed by the mail RFC and to make it easy to remove if a particular set of characters should be disallowed in your system due to special processing requirements (like blocking of possible sql injection attacks)
No Escape: for the mailbox name I've only included dot-atom format, I've intentionally excluded dot or slash escaped support
Subtle Letters: For some parts I've used [^\W\d_] instead of [a-zA-Z] to improve support for languages other than english.
Out of Bounds: Due to idiosyncrasies in capture group processing in some systems I've used + in place of {,61}. If you're using it someplace that might be vulnerable to buffer overflow attacks remember to bound your inputs
Credits: Modified from community post by Tripleaxis, which was in turn taken from the .net helpfiles