0

I am working on mail client application. I want to show all HTTP links as clickable hyper links.

I have noticed that some clients are sending HTTP links without enclosing them inside the anchor tags. In this case I am failing to show those links as clickable links.

My requirement is to find all HTTP links in a HTML mail and need to replace those links by enclosing them within anchor tags and also I need to exclude the links which are already in anchor tags or in source attribute of any tag.

Ex: Suppose my HTML mail is having the following text

Input:  "http://www.google.com/"     < a href = "http:\\gmail.com"></a>

After replacing I want the following out put

Output: <a href = "http://www.google.com"> </a> < a href = "http:\\gmail.com"></a>

I think I can not directly look for pattern which starts with http... because it can also come as src of any tag.

So Can some one help me to solve these issue

Thanks in advance

Subbi

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
Subbi Reddy K
  • 392
  • 1
  • 2
  • 14
  • What exact technology is this mail client application based on and/or written in? Also I added the regex tag -- since that was part of the question, but regex will NOT be a very robust solution. – Brock Adams Aug 03 '10 at 14:48
  • `http:\\gmail.com` is an invalid address. Protocol name is followed by `'//'`. Browsers may accept it and make amends internally, but `curl` will not :) – Anurag Aug 03 '10 at 16:32
  • Look at this post: http://stackoverflow.com/questions/37684/replace-url-with-html-links-javascript –  May 17 '11 at 15:01

3 Answers3

2

I believe you can't do it properly in one regexp; and also, obligatory link. Why are you keen on doing it with regexp if you're working in JavaScript? Your interpreter is boxed together with the archetypal HTML parsing engine: a web browser. Just delve into DOM and replace on text nodes.

If you're not doing it in JS and the tag is just misleading, and you can't find a decent HTML parsing library, then your best bet is to split the string by tags, replace on non-tag elements, then join back up, I think.

Community
  • 1
  • 1
Amadan
  • 191,408
  • 23
  • 240
  • 301
  • That link is awesome: "Even Jon Skeet cannot parse HTML using regular expressions." :D – FK82 Aug 04 '10 at 15:03
0

Check this:

(function($){
  $.fn.hyperlinkRegex = function(regex, target, ismailto) {
    ismailto = ismailto || false;
    if(regex == undefined || regex.source == '') {
      $(this).find('a').each(function(){
        $(this).replaceWith($(this).text());
        $(this).parent().each(function(){
          node = $(this).get(0);
          if(node.normalize) node.normalize();
        });
      });
    } else {
      $(this).each(function(){
        elt = $(this).get(0)
        elt.normalize();
        $.each($.makeArray(elt.childNodes), function(i, node){
          if(node.nodeType == 3) {
            var searchnode = node
            while((pos = searchnode.data.search(regex)) >= 0) {
              match = searchnode.data.slice(pos).match(regex)[0];
              if(match.length == 0) break;
              var anode = document.createElement('a');
              var middlebit = searchnode.splitText(pos);
              var searchnode = middlebit.splitText(match.length);
              var middleclone = middlebit.cloneNode(true);
              anode.appendChild(middleclone);
              if (ismailto == true) {
                anode.href = "mailto:" + middleclone.nodeValue;
              } else {
                anode.href = middleclone.nodeValue;
              }
              anode.target = target;
              searchnode.parentNode.replaceChild(anode, middlebit);
            }
          } else {
            $(node).hyperlinkRegex(regex, target, ismailto);
          }
        })
      })
    }
    return $(this);
  }
})(jQuery);

Usage:

// basic links
var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
node.hyperlinkRegex(exp, "_blank", false);
// email
exp = /(\b[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b)/ig;
node.hyperlinkRegex(exp, "_blank", true);

Let me know this solves your problem

ManojMarathayil
  • 712
  • 11
  • 28
0

I just tested this expression:

/\s+("http:[^\s]+")\s+/g 

This will replace every quoted URL enclosed by whitespace. You use it like this:

var string = "\"http://www.google.com/\"     < a href = \"http:\\gmail.com\"></a>" ; //!! the email string you provided
var replaced = string.replace(/\s+("http:[^\s]+")\s+/g," <a href=$1></a> ") ;

Other than that, javascript does not support (negative) lookbehind in regex which one would need to perfectly identify whether the matched URL was within a html tag or not.

HTH ,

FK

FK82
  • 4,907
  • 4
  • 29
  • 42