Convert Text into Hyperlinks <a> and Image tags <img>

Viewed 78

I am using this function to convert text into clickable links (<a href=""> </a>) and image urls into img tags (<img src="" />).

const parsecontent = (text)=>{
    var ishyperlink= /([^\S]|^)((https?\:\/\/)(\S+))/gi;
    return (text || "").replace(ishyperlink,
    function(match, space, url){
       var isimglink = /https?:\/\/.*\.(?:png|jpg|gif|jpeg)/i;
        if (url.match(isimglink)) {
         return space + '<a href="' + url + '"><img src="' + url + '" /></a>';
        }
     return space + '<a href="' + url + '">' + url + '</a>';
    }
  );
}

Using like this

const div = document.querySelector("#content");
div.innerHTML = parsecontent(div.innerHTML);

It works fine, if the content with proper spaces. It links, image urls not separated with spaces it fails. Can you pls help me to fix this?

Codepen here https://codepen.io/dagalti/pen/GRqpYLp

screen

1 Answers

I came up with a regex that's tailored to satisfy your test cases.

This regex is how we will match for a URL:

((https?\:\/\/)([\w!"#$%&\'()*+,-./@:;=\^_`{|}~]*))

In your example, we have 2 urls together with no whitespace in between. What happens if we have a url and a non-url string with no whitespace between? We could terminate the match when it reaches a TLD (such as .com, .org, etc). To satisfy your example however, I am making the assumption that we are dealing with 2 urls separated by no whitespace. In that case, we want to terminate the match when we notice the start of a new url (?=https?):

([^\S]|^)((https?\:\/\/)([\w!"#$%&\'()*+,-./@:;=\^_`{|}~]*))(?=https?)

Next we want to match the urls that are surrounded by whitespace:

((https?\:\/\/)([\w!"#$%&\'()*+,-./@:;=\^_`{|}~]*))

Putting all this together we get this regex:

([^\S]|^)((https?\:\/\/)([\w!"#$%&\'()*+,-./@:;=\^_`{|}~]*))(?=https?)|((https?\:\/\/)([\w!"#$%&\'()*+,-./@:;=\^_`{|}~]*))

We have to adjust your replace logic a bit too:

const parsecontent = (text)=>{
    var ishyperlink= /([^\S]|^)((https?\:\/\/)([\w!"#$%&\'()*+,-./@:;=\^_`{|}~]*))(?=https?)|((https?\:\/\/)([\w!"#$%&\'()*+,-./@:;=\^_`{|}~]*))/gi;
    return (text || "").replace(ishyperlink,
    function(url){
       var isimglink = /https?:\/\/.*\.(?:png|jpg|gif|jpeg)/i;
        if (url.match(isimglink)) {
         return '<a href="' + url + '"><img src="' + url + '" /></a>';
        }
     return '<a href="' + url + '">' + url + '</a>';
    }
  );
}

This regex is quite verbose, there may be more succinct ways of satisfying your test cases (I'm not a regexpert though)

Related