Q:

How can I return the length of each link in a string using JavaScript?

I need to calculate length and number of links in a string in JavaScript.
Here's an example of what I'm looking to do:
var myString = 'Lorem ipsum dolor sit amet, www.google.com/abc consectetur adipiscing elit. http://stackoverflow.com/question/ask Donec sed magna ultricies.'
function getLinkLength(myString) {
    // do stuff. ha!
    return linkArray; // returns [0] => 18, [1] => 37
}

Output should tell me the length of all links in a string, like so:
www.google.com/abc = 18
http://stackoverflow.com/question/ask = 37

Can you help me parse a string for links and return the length of each string?  Email addresses should also count as links (ex. email@domain.com = 16).
This is for a character counter where I don't want to penalize characters for link length, so I need to subtract the length of all links in a string for my counter.
Here are some Regex's I'm looking to use.  I realize these aren't perfect, but if I can handle the basic links I'll sacrifice the corner cases.
regexes.email = /^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!\.)){0,61}[a-zA-Z0-9]?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/;
regexes.url = /^(?:(?:ht|f)tp(?:s?)\:\/\/|~\/|\/)?(?:\w+:\w+@)?((?:(?:[-\w\d{1-3}]+\.)+(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|edu|co\.uk|ac\.uk|it|fr|tv|museum|asia|local|travel|[a-z]{2}))|((\b25[0-5]\b|\b[2][0-4][0-9]\b|\b[0-1]?[0-9]?[0-9]\b)(\.(\b25[0-5]\b|\b[2][0-4][0-9]\b|\b[0-1]?[0-9]?[0-9]\b)){3}))(?::[\d]{1,5})?(?:(?:(?:\/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|\/)+|\?|#)?(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?:#(?:[-\w~!$ |\/.,*:;=]|%[a-f\d]{2})*)?$/i;
regexes.cc = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/,
regexes.urlsafe = /^[^&$+,\/:=?@ <>\[\]\{\}\\^~%#]+$/;

A:

Your URL regex looks like it is probably both serious overkill as well as misses certain cases.
It is probably better to go with a far simpler URL regex (unless you have an explicit reason for needing that particular pattern).
Here is a JSFiddle which does the trick: http://jsfiddle.net/m5ny4/1/
var input = "http://google.com google.com/abc pie@pie.com cookies@some.longer.domain www.cookies.com ftps://a.b.c.d/cookies someone@gmail.com";
var pattern = /(?:[^\s]+@[a-z]+(\.[a-z]+)+)|(?:(?:(?:[a-z]+:\/\/)|\s)[a-z]+(\.[a-z]+)+(\/[^\s]*)?)/g;

var matches = input.match(pattern);

for (var i = 0, len = matches.length; i < len; i++) {
    $('ul').append('<li>' + matches[i] + " = " + matches[i].length + '</li>');
}

The pattern I use is both email and URLs, but greatly simplified from the ones you showed above. It could be reduced down a bit (combine them more closely), but I chose to keep them separate and just pipe them together because its easier to read.
The regex basically has two big blocks: (?:[^\s]+@[a-z]+(\.[a-z]+)+) and (?:(?:(?:[a-z]+:\/\/)|\s)[a-z]+(\.[a-z]+)+(\/[^\s]*)?)
The first block is for email. Ignore the (?: ) wrapping around it, and you have [^\s]+@[a-z]+(\.[a-z]+)+. The [^\s]+ matches any non-white-space character before an @ sign. Afterwords, it matches any domain with any number of sub or top level domains (e.g., google.com, google.co.uk).
The second one (?:(?:(?:[a-z]+:\/\/)|\s)[a-z]+(\.[a-z]+)+(\/[^\s]*)?) is the URL one. The first meaningful section is (?:[a-z]+:\/\/)|\s), which would match any protocol or a white-space character (to tell it where the start is). If you want to restrict it to certain protocols, you would just replace [a-z]+ with the protocols you want.
Next is [a-z]+ which matches the first (sub)domain, followed by (\.[a-z]+)+ which matches one or more additional domains (since you need at least two to make a legitimate domain name). Finally, we have (\/[^\s]*) which optionally matches everything until it finds a white-space.
The rest is pretty simple. Do the match globally (the g at the end of the pattern) to get all occurrences, then just loop through them and use .length on the strings to get their length.
I just output them in to a list, but you can do whatever you want by replacing the for loop.

