2
votes

I have a email validation regex. what i want to achieve is, if any email does not match the regex pattern, I want to display only those characters which match with the regex and strip away which do not.

pattern=r'(^a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)'

For example: if my validation fails because there is "'" and '?' in email, then my suggested email should be with all characters except these two. If the input doesnot match the pattern then:

input="t'[email protected]"    
expected output = "[email protected]"

How can I achieve this? Currently I am using,

z=list(input)
sp=[]
for j in range(len(z)):
    result=re.findall(pattern,z[j])
    if len(result)!=0:
        sp.append(result[0])
output=''.join(sp)

However, this is giving me a blank output. Apart from this, another problem with this approach is, it will not detect an anomally, if the email input has 2'@'

Can anyone suggest what will be the correct way of proceeding here?

1

1 Answers

0
votes

If you assume there are at least one @ and at least one . after it in the string, upon your main validation regex failure, you may capture the three parts of the email, and remove all unwanted chars from the them and concatenate back into a "clean" email:

import re
pattern = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)+$'
text = "t'[email protected]"
def repl(x):
    return "{}@{}.{}".format(re.sub(r'[^a-zA-Z0-9_.+-]+', '', x.group(1)),
        re.sub(r'[^a-zA-Z0-9.-]+', '', x.group(2)),
        re.sub(r'[^a-zA-Z0-9.-]+', '', x.group(3)))

if re.fullmatch(pattern, text):
    print("Valid email: {}".format(text))
else:
    email = re.sub(r"(.*)@(.*)\.(.*)", repl, text)
    print("Filtered email: {}".format(email))

See the Python demo, output is Filtered email: [email protected].

There is another way to clean the part after @: split with . and remove all chars matching [^a-zA-Z0-9-]+ in all of them, and then concatenate them back:

def repl(x):
    return "{}@{}".format(re.sub(r'[^a-zA-Z0-9_.+-]+', '', x.group(1)),
        ".".join([re.sub(r'[^a-zA-Z0-9-]+', '', y) for y in x.group(2).split('.')]) )

See this Python demo.