1

I have a text as follows

For further details, please contact abc.helpdesk@xyz.com

I want to replace the email ID mentioned in the above text by <a href "abc.helpdesk@xyz.com">abc.helpdesk@xyz.com</a> So that the email ID would become a clickable object when the above text would be presented on web page

So far I have tried out following

text = 'For further details, please contact abc.helpdesk@xyz.com'
email_pat = re.findall(r'[\w\.-]+@[\w\.-]+\.\w+',text)
email_str = ' '.join(email_pat) #converts the list to string
text_rep = ext.replace(email_str,'<a href "email_str">email_str</a>')

The above code replace the email string but instead of creating hyperlink it actually does the following

For further details, please contact <a href "email_str">email_str</a>

Is there any way to tackle this?

Edit When I am using the above solution in Flask, on frontend I am getting the desired result (i.e. email ID becomes clickable, urls become clickable). But when I click on this I am being redirected to the localhost:5002 instead of opening the Outlook. localhost:5002 is where my Flask App is being hosted. Even for the url also it is not working. I am using the following code to make the url string clickable.

text = text.replace('url',f'<a href "{url_link}">{url}</a>'

The above code is making the usr string clickable, but upon clicking it is being redirected to localhost:5002 Is there any change I need to make in app.run(host=5002) method?

pythondumb
  • 1,187
  • 1
  • 15
  • 30
  • Possible duplicate of [python re.sub, only replace part of match](https://stackoverflow.com/questions/32698614/python-re-sub-only-replace-part-of-match) – tripleee Jan 21 '19 at 05:15
  • You probably want to make the prefic the href attribute with "mailto:" to have a click automatically open an email client - `abc.helpdesk@xyz.com` – snakecharmerb Jan 22 '19 at 08:58
  • `@snakechamberb` I did this exactly and it was working fine. Thanks anyway. However, can you help me with URL part? I am still struggling. – pythondumb Jan 22 '19 at 09:58

2 Answers2

4

You can use re.sub with a lambda:

import re
s = 'For further details, please contact abc.helpdesk@xyz.com'
new_s = re.sub('[\w\.]+@[\w\.]+', lambda x:f'<a href="{x.group()}">{x.group()}</a>', s)

Output:

'For further details, please contact <a href="abc.helpdesk@xyz.com">abc.helpdesk@xyz.com</a>'
Ajax1234
  • 69,937
  • 8
  • 61
  • 102
1

Your actual problem is the line:

text_rep = ext.replace(email_str, '<a href "email_str">email_str</a>')

That does exactly what you say it does, but what you want is this:

text_rep = ext.replace(email_str, f'<a href "{email_str}">{email_str}</a>')

Instead of replacing the mail address with that literal string with email_str in it, this formats the string so that it has the mail address in it. This is assuming you run Python 3, for Python 2 it would be more like:

text_rep = ext.replace(email_str, '<a href "{email_str}">{email_str}</a>'.format(email_str=email_str))

However, note that your regex to match mail addresses makes some assumptions, a better version can be found here Are email addresses allowed to contain non-alphanumeric characters?

Also, your code assumes there will be only one mail address in the source text string, as you're joining results. A better solution might be one which replaces each individual mail addresses with the correct replacement.

import re

input_text = 'For further details, contact admin@mywebsite.org or the webmaster webmaster123@hotmail.com'

output_text = re.sub(
    r'(?sm)(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})',
    r'<a href="\g<0>">\g<0></a>', input_text)

print(output_text)

Note that this needs nothing but a basic re.sub.

Grismar
  • 27,561
  • 4
  • 31
  • 54
  • Thats great `@Grismar`. Can you suggest how to pick up multiple 'urls' using this same technique? I have got a regex which is pretty long. – pythondumb Jan 21 '19 at 06:46
  • The regex to pick up any URL will be very long, sadly - a URL is long, complex and varied, so there is no short way about it. This question has one in a good solution that clocks in at 5497 characters. At that point, you have to wonder if a regex is the best solution, or if you should get users to mark URLs as links when writing. https://stackoverflow.com/questions/161738/what-is-the-best-regular-expression-to-check-if-a-string-is-a-valid-url - the approach would be the same though. – Grismar Jan 22 '19 at 00:33