Phone number/email regex verifier Is there anything I can do better here? I tried looking for ways to simplify this with comprehension but could not figure out how and was told it is better to explicitly use for loops.

import re

print("This is a email/phone number parser.")
print("Type in the name of the file you want to parse:\n")
filename = input("&gt; ")

emailregex = re.compile(r'''
([a-z0-9\.]+)
(@)
([a-z0-9\.]+)
(\.)
([a-z]{2,4})
''', re.VERBOSE | re.IGNORECASE)


phoneregex = re.compile(r'''
(\+\d)?
(-)?
(\d{3}|\(\d{3}\))?
(\.|-|\s)?
(\d{3})
(\.|-|\s)
(\d{4})
''', re.VERBOSE)

with open(filename, 'r') as filename:
    filedata = filename.read()
    emailmo = emailregex.findall(filedata)
    phonemo = phoneregex.findall(filedata)

print("Emails: \n")
for email in emailmo:
    for group in email:
        print(group, end='')
    print()

print()

print("Phone numbers: \n")
for pn in phonemo:
    for group in pn:
        print(group, end='')
    print()
The regular expression for email that matches 100% accurately would be a sight to see.  One answer to this related question claims to do that.  It certainly is horrendous, so I won't complain that yours isn't completely accurate.  While a phone-number is relatively simple, the possibilities are more than you might think.  For example, not all countries require ten digits.  The ITU has defined the maximum number of digits to be 15.  You can then take into account that the country code might not have a plus sign (+) before it.  It might be something like 1-800-123-4567.  The number of possibilities grows the more one thinks about it, so I won't complain.  I'm merely pointing it out.



I would use re.finditer() instead of re.findall().  That means that instead of getting a list of tuples, you get an iterator of matches.  With that, it becomes:

for email in emailmo:
    print(email.group())


and similar for the phone numbers.



There are two ways that I see to do the list comprehension (with re.finditer()):


[print(pn.group()) for pn in phonemo]
print('\n'.join([pn.group() for pn in phonemo]))


The first is positively sickening.  It creates a list as long as the number of phone numbers or email addresses, and that list isn't even used.  The second is a little more to my liking, but I do believe that the explicit for loop is better.  For your curiosity, the old code in similar comprehensions could be horrendous:

[print(''.join(pn)) for pn in phonemo]


or ... horrendous:

print('\n'.join([''.join(pn) for pn in phonemo]))