When you don't care about casing, rather than repeating
A-Za-z multiple times, it can be preferable to use the case-insensitive flag; this makes the pattern terser and more readable, as well as less error-prone.
It would also be good to use informative variable names; the variable name
x is not very useful. Maybe call it
You can also consider putting spaces between operators (like
=) and arguments (after a
,), to make the code more readable.
You can also consider using
re.match instead of
re.match will produce a match only if the pattern matches starting at the beginning of the input string. (In contrast,
re.search will permit a match anywhere within the input string.) While this won't alter the meaning of your code since you're using
^, it can make the code a bit more readable when a reader can see at a glance, without even looking at the pattern, "Oh, you're using
.match, so the pattern is intended to match from the start of the string."
pattern = r"^[a-z]+[-_$.a-z]*@[a-z]*\.[a-z]+$"
match = re.match(pattern, "firstname.lastname@example.org", re.IGNORECASE)
Another way, rather than
re.IGNORECASE, is to put an inline modifier at the beginning of the pattern:
pattern = r"(?i)^[a-z]+[-_$.a-z]*@[a-z]*\.[a-z]+$"
That's how I'd refactor your current code and its logic - but, as has been said, true email address validation is much more complicated.
On a completely different note, I notice this is Python 2, which is end-of-life and no longer supported by bug fixes, security improvements, etc. Upgrading may not be possible in certain codebases, but consider changing to Python 3 if at you can.