使用
^(?!.*\.TEST@)[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*\.(?:COM|EDU)$
见proof。
说明
--------------------------------------------------------------------------------
^ the beginning of the string
--------------------------------------------------------------------------------
(?! look ahead to see if there is not:
--------------------------------------------------------------------------------
.* any character except \n (0 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
\. '.'
--------------------------------------------------------------------------------
TEST@ 'TEST@'
--------------------------------------------------------------------------------
) end of look-ahead
--------------------------------------------------------------------------------
[a-zA-Z0- any character of: 'a' to 'z', 'A' to 'Z',
9.!#$%&'*+/=?^_`{|}~- '0' to '9', '.', '!', '#', '$', '%', '&',
]+ ''', '*', '+', '/', '=', '?', '^', '_',
'`', '{', '|', '}', '~', '-' (1 or more
times (matching the most amount possible))
--------------------------------------------------------------------------------
@ '@'
--------------------------------------------------------------------------------
[a-zA-Z0-9-]+ any character of: 'a' to 'z', 'A' to 'Z',
'0' to '9', '-' (1 or more times (matching
the most amount possible))
--------------------------------------------------------------------------------
(?: group, but do not capture (0 or more times
(matching the most amount possible)):
--------------------------------------------------------------------------------
\. '.'
--------------------------------------------------------------------------------
[a-zA-Z0-9-]+ any character of: 'a' to 'z', 'A' to
'Z', '0' to '9', '-' (1 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
)* end of grouping
--------------------------------------------------------------------------------
\. '.'
--------------------------------------------------------------------------------
(?: group, but do not capture:
--------------------------------------------------------------------------------
COM 'COM'
--------------------------------------------------------------------------------
| OR
--------------------------------------------------------------------------------
EDU 'EDU'
--------------------------------------------------------------------------------
) end of grouping
--------------------------------------------------------------------------------
$ before an optional \n, and the end of the
string