2014-02-24 40 views
0

我需要計算JavaScript中字符串中鏈接的長度和數量。如何使用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)。

這是爲字符計數器,我不想懲罰鏈接長度的字符,所以我需要減去字符串中的所有鏈接的長度爲我的櫃檯。

這是我正在使用的一些正則表達式。我意識到這些並不完美,但如果我能處理基本的聯繫,我會犧牲角落的情況。

regexes.email = /^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~][email protected](?:(?:(?:[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+:\[email protected])?((?:(?:[-\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 = /^[^&$+,\/:[email protected] <>\[\]\{\}\\^~%#]+$/; 

回答

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][email protected][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>'); 
} 

我使用的模式是電子郵件和網址,但是從你上面顯示的那些大大簡化。它可以減少一點(將它們更緊密地結合在一起),但我選擇讓它們分開,並將它們連接在一起,因爲它更易於閱讀。

正則表達式主要有兩大塊:(?:[^\s][email protected][a-z]+(\.[a-z]+)+)(?:(?:(?:[a-z]+:\/\/)|\s)[a-z]+(\.[a-z]+)+(\/[^\s]*)?)

第一塊是電子郵件。忽略(?:)環繞它,你有[^\s][email protected][a-z]+(\.[a-z]+)+[^\s]+匹配@符號前的任何非空白字符。後綴,它與任何數量的子或頂級域名(例如,google.com,google.co.uk)匹配的域名。

第二個(?:(?:(?:[a-z]+:\/\/)|\s)[a-z]+(\.[a-z]+)+(\/[^\s]*)?)是網址之一。第一個有意義的部分是(?:[a-z]+:\/\/)|\s),它可以匹配任何協議或空白字符(告訴它開始的位置)。如果您想將其限制爲某些協議,則只需將[a-z]+替換爲所需的協議即可。

接下來是[a-z]+它匹配第一個(子)域,然後是(\.[a-z]+)+匹配一個或多個額外的域(因爲您至少需要兩個才能合法的域名)。最後,我們有(\/[^\s]*),它可以選擇匹配所有內容,直到找到一個空格。

其餘的很簡單。在全局範圍內執行匹配(模式末尾的g)以獲取所有匹配項,然後循環遍歷它們並使用字符串上的.length來獲得它們的長度。

我只是將它們輸出到列表中,但是您可以通過替換for循環來執行任何您想要的操作。

+0

哇!這是快速和全面的。謝謝!像魅力一樣工作。 – Ryan

相關問題