Как я могу вернуть длину каждой ссылки в строке, используя JavaScript?

0

Мне нужно рассчитать длину и количество ссылок в строке в JavaScript.

Вот пример того, что я хочу сделать:

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
}

Результат должен указывать длину всех ссылок в строке, например:

www.google.com/abc = 18
http://stackoverflow.com/question/ask = 37

Можете ли вы помочь мне разобрать строку для ссылок и вернуть длину каждой строки? Адреса электронной почты также должны считаться ссылками (например, [email protected] = 16).

Это для счетчика символов, где я не хочу наказывать символов за длину ссылки, поэтому мне нужно вычесть длину всех ссылок в строке для моего счетчика.

Вот некоторые Regex, которые я ищу использовать. Я понимаю, что они не идеальны, но если я смогу справиться с основными связями, я пожертвую угловыми делами.

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 = /^[^&$+,\/:=?@ <>\[\]\{\}\\^~%#]+$/;
Теги:

1 ответ

2
Лучший ответ

Регулярное URL-адрес выглядит, вероятно, как серьезным, так и пропуском определенных случаев.

Вероятно, лучше перейти с гораздо более простым URL-адресом регулярного выражения (если у вас нет явной причины для использования этого конкретного шаблона).

Вот JSFiddle, который делает трюк: http://jsfiddle.net/m5ny4/1/

var input = "http://google.com google.com/abc [email protected] [email protected] www.cookies.com ftps://a.b.c.d/cookies [email protected]";
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>');
}

Образец, который я использую, - это электронная почта и URL-адреса, но значительно упрощенные из тех, которые вы указали выше. Его можно немного уменьшить (объединить их ближе), но я решил сохранить их отдельно и просто соединить их, потому что его легче читать.

Регулярное выражение имеет два больших блока: (?:[^\s]+@[az]+(\.[az]+)+) и (?:(?:(?:[az]+:\/\/)|\s)[az]+(\.[az]+)+(\/[^\s]*)?)

Первый блок предназначен для электронной почты. Игнорируйте обертывание (?: ) :) Вокруг него, и вы [^\s]+@[az]+(\.[az]+)+. [^\s]+ соответствует любому символу небелого пробела перед знаком @. Послесловие, оно соответствует любому домену с любым количеством доменов sub или верхнего уровня (например, google.com, google.co.uk).

Второй (?:(?:(?:[az]+:\/\/)|\s)[az]+(\.[az]+)+(\/[^\s]*)?) является URL-адресом. Первый значащий раздел - (?:[az]+:\/\/)|\s), который будет соответствовать любому протоколу или символу пробела (указать, где начинается старт). Если вы хотите ограничить его определенными протоколами, вы просто замените [az]+ на нужные вам протоколы.

Далее будет [az]+ который соответствует первому (под) домену, за которым следует (\.[az]+)+ который соответствует одному или нескольким дополнительным доменам (так как вам нужно как минимум два, чтобы сделать законное доменное имя). Наконец, мы имеем (\/[^\s]*) который необязательно соответствует всем, пока не найдет пустое пространство.

Остальное довольно просто. Сделайте совпадение глобально (g в конце рисунка), чтобы получить все вхождения, затем просто .length их и используйте .length в строках, чтобы получить их длину.

Я просто выводю их в список, но вы можете делать все, что захотите, заменив цикл for.

  • 0
    Вау! Это было быстро и всесторонне. Спасибо! Работал как шарм.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню