2011-04-19 61 views
88

是否有一個JavaScript的方法來檢查一個字符串是否是一個網址?檢查一個JavaScript字符串是一個URL

正則表達式被排除,因爲URL是最有可能這樣寫stackoverflow;也就是說,它可能沒有一個.COM,WWW或http

+8

如果缺少'http',它是每默認沒有URL。 – nfechner 2011-04-19 13:29:10

+0

@nfechner這就是說,如果它沒有指定一個協議並使用冒號字符(最好是下兩個正斜槓),那麼它不是一個URL? – jcolebrand 2011-04-19 13:30:56

+0

@marcel,因爲算法會在名稱後附加.com,.net,.biz,.org,.gov,.mil等,並根據特定的優先順序測試它是否有效。或者,他們問谷歌是否可能是一個域名。 – jcolebrand 2011-04-19 13:31:39

回答

35

與回答一個相關的問題:

Javascript regex URL matching

或者從Devshed這個正則表達式:

function ValidURL(str) { 
    var pattern = new RegExp('^(https?:\/\/)?'+ // protocol 
    '((([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}|'+ // domain name 
    '((\d{1,3}\.){3}\d{1,3}))'+ // OR ip (v4) address 
    '(\:\d+)?(\/[-a-z\d%_.~+]*)*'+ // port and path 
    '(\?[;&a-z\d%_.~+=-]*)?'+ // query string 
    '(\#[-a-z\d_]*)?$','i'); // fragment locater 
    if(!pattern.test(str)) { 
    alert("Please enter a valid URL."); 
    return false; 
    } else { 
    return true; 
    } 
} 
+0

感謝您的回答,但我無法使用正則表達式。 – Bruno 2011-04-19 13:32:52

+0

@布魯諾,怎麼回事?解決這些問題最好。 – 2011-04-19 13:33:36

+1

我知道,但我在我的書籤搜索,其中大部分是這樣寫計算器(無.COM等) – Bruno 2011-04-19 13:35:13

141
function isURL(str) { 
    var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol 
    '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|'+ // domain name 
    '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address 
    '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path 
    '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string 
    '(\\#[-a-z\\d_]*)?$','i'); // fragment locator 
    return pattern.test(str); 
} 
+0

返回false爲 「磁體:XT =甕:btih:123」 – holden321 2013-11-11 15:25:34

+13

返回'HTTP假://en.wikipedia.org/wiki/Procter _&_ Gamble' – Sorter 2013-12-14 19:48:26

+5

失敗的谷歌搜索圖片鏈接:'的http:// WWW。 google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&docid=nIv5rk2GyP3hXM&tbnid=isiOkMe3nCtexM:&ved=0CAUQjRw&url=http%3A%2F%2Fanimalcrossing.wikia.com%2Fwiki%2FLion&ei=ygZXU_2fGKbMsQTf4YLgAQ&bvm=bv.65177938, d.aWc&PSIG = AFQjCNEpBfKnal9kU7Zu4n7RnEt2nerN4g&烏斯= 1398298682009707' – 2014-04-23 00:23:52

3

我不能說是最接近#5717133後發表評論,但下面是我想出如何讓@ TOM-gullen正則表達式的工作方式。

/^(https?:\/\/)?((([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}|((\d{1,3}\.){3}\d{1,3}))(\:\d+)?(\/[-a-z\d%_.~+]*)*(\?[;&a-z\d%_.~+=-]*)?(\#[-a-z\d_]*)?$/i 
+1

這對我有用,但我需要反斜槓反斜槓。 'var pattern = new RegExp('(https?:\\/\\ /)?((([az \\ d]([az \\ d - ] * [az \\ d])*)\\。 )+ [AZ] {2,} |((\\ d {1,3} \\。){3} \\ d {1,3}))(\\:\\?d +)(\\/[-az \\ d%_〜+。] *)*(\\ [;&AZ \\ d%_〜+ = - ]?*)(\\#[ - AZ \\ d _] * )?'','i');' – 2016-06-20 21:29:16

19

爲了驗證URL使用javascript如下所示

function ValidURL(str) { 
    var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/; 
    if(!regex .test(str)) { 
    alert("Please enter valid URL."); 
    return false; 
    } else { 
    return true; 
    } 
} 
+2

正則表達式的幾個部分可以大大減少:a)'(http | https)'到'(?:https?)';' b)':{0,1}'到':?'; c)'[0-9]'到'\ d' – 2017-03-28 14:52:59

46

而不是使用一個正則表達式,我建議利用一個錨定元件的。

當你設置一個 anchorhref財產

,其他各種屬性設置。

var parser = document.createElement('a'); 
parser.href = "http://example.com:3000/pathname/?search=test#hash"; 

parser.protocol; // => "http:" 
parser.hostname; // => "example.com" 
parser.port;  // => "3000" 
parser.pathname; // => "/pathname/" 
parser.search; // => "?search=test" 
parser.hash;  // => "#hash" 
parser.host;  // => "example.com:3000" 

source

然而,如果值href勢必是不是一個有效的URL,那麼這些輔助屬性的值將是空字符串。

編輯:正如在評論中指出的那樣:如果使用了一個無效的url,那麼當前URL的屬性可能會被替換。

所以,只要你不是在傳遞當前頁面的URL,你可以這樣做:

function isValidURL(str) { 
    var a = document.createElement('a'); 
    a.href = str; 
    return (a.host && a.host != window.location.host); 
} 
+3

事實並非如此(至少在Chrome 48中)。如果傳遞給'a.href'的url無效,'parser.host'返回當前頁面的主機名,而不是期望的'false'。 – 2016-02-25 15:37:15

+1

嘎!這很奇怪。我發誓我測試了這個!我認爲可以公平地說,這不會在當前頁面上使用,所以條件可以改變。我將編輯帖子。 – LukeP 2016-02-25 22:48:32

+0

這不是一個非常典型的用例,但是這種技術在Firefox瀏覽器窗口的上下文中不起作用(對於插件開發很重要) – chrmod 2016-05-15 16:01:48

6

你可以嘗試使用URL constructor:如果不扔,字符串是有效的URL:

const isValidUrl = (string) => { 
    try { 
    new URL(string); 
    return true; 
    } catch (_) { 
    return false; 
    } 
} 
+0

這會引發諸如www.google.com之類的字符串的例外,表明這不是有效的URL,但它是有效的URL – AshD 2017-04-21 01:04:29

+0

看起來不錯,希望很快離開實驗階段。 – gmo 2017-06-09 10:50:21

1

(我沒有代表對ValidURL例如發表評論;雖然不鼓勵使用協議相對網址(The Protocol-relative URL因此張貼此作爲一個答案。)

),他們得到有時使用。要使用正則表達式的協議部分可能是可選的,例如:驗證這樣一個URL

function isValidURL(str) { 
    var pattern = new RegExp('^((https?:)?\\/\\/)?'+ // protocol 
     '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name 
     '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address 
     '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path 
     '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string 
     '(\\#[-a-z\\d_]*)?$','i'); // fragment locater 
    if (!pattern.test(str)) { 
     return false; 
    } else { 
     return true; 
    } 
} 

正如其他人指出的那樣,正則表達式似乎並沒有被用於驗證網址,最適合的方式,雖然。

10

改進公認的答案...

  • 具有雙重轉義反斜槓(\\)
  • 確保域有一個點和擴展名(.com .IO名爲.xyz)
  • 在路徑中允許完整冒號(:),例如http://thingiverse.com/download:1894343
  • 允許在路徑號(&)e.g http://en.wikipedia.org/wiki/Procter_&_Gamble
  • 允許@符號在路徑例如https://medium.com/@techytimo

    isURL(str) { 
        var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol 
        '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name and extension 
        '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address 
        '(\\:\\d+)?'+ // port 
        '(\\/[-a-z\\d%@_.~+&:]*)*'+ // path 
        '(\\?[;&a-z\\d%@_.,~+&:=-]*)?'+ // query string 
        '(\\#[-a-z\\d_]*)?$','i'); // fragment locator 
        return pattern.test(str); 
    } 
    
+0

這應該是被接受的答案。謝謝! – 2018-03-07 17:03:23

1

一個功能,我一直用它來驗證URL「串」是:

var matcher = /^(?:\w+:)?\/\/([^\s\.]+\.\S{2}|localhost[\:?\d]*)\S*$/; 

function isUrl(string){ 
    return matcher.test(string); 
} 

這個函數會返回一個布爾值的字符串是否是一個URL。

0

由於已經注意到了完美的正則表達式是難以捉摸,但似乎仍是一個合理的方法(方案是服務器端的測試或新的實驗URL API)。然而,高排名的答案往往返回常見的URL假,但更糟糕將會凍結您的應用程序/頁分鐘甚至簡單的字符串作爲isURL('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')。在一些評論中已經指出,但很可能沒有看到它的壞價值。像這樣掛起使得代碼在任何嚴重的應用程序中都不可用。我認爲這是由於重複的不區分大小寫的套狀((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|' ...代碼。拿出'我',它不掛,但當然不會按需要工作。但即使使用忽略大小寫標誌,這些測試也會拒絕允許的高Unicode值。

已經提到過的最好的是:

function isURL(str) { 
    return /^(?:\w+:)?\/\/([^\s\.]+\.\S{2}|localhost[\:?\d]*)\S*$/.test(str); 
} 

這來自Github上segmentio/is-url。關於代碼庫的好處是你可以看到測試和任何問題,還有測試字符串貫穿它。有一個分支會允許字符串丟失協議,如google.com

還有另外一個庫我已經看到了在dperini/regex-weburl.js爲ISURL甚至更好,但它是非常複雜的。它有一個更大的有效和無效URL測試列表。簡單的一個上面還通過了所有的正面和唯一未能阻止像http://a.b--c.de/一些奇怪的底片,以及特殊的IPS。

無論您選擇哪種方式,都可以使用瀏覽器的開發者工具inpector,通過dodeini/regex-weburl.js上的測試調整此函數。

function testIsURL() { 
//should match 
console.assert(isURL("http://foo.com/blah_blah")); 
console.assert(isURL("http://foo.com/blah_blah/")); 
console.assert(isURL("http://foo.com/blah_blah_(wikipedia)")); 
console.assert(isURL("http://foo.com/blah_blah_(wikipedia)_(again)")); 
console.assert(isURL("http://www.example.com/wpstyle/?p=364")); 
console.assert(isURL("https://www.example.com/foo/?bar=baz&inga=42&quux")); 
console.assert(isURL("http://✪df.ws/123")); 
console.assert(isURL("http://userid:[email protected]:8080")); 
console.assert(isURL("http://userid:[email protected]:8080/")); 
console.assert(isURL("http://[email protected]")); 
console.assert(isURL("http://[email protected]/")); 
console.assert(isURL("http://[email protected]:8080")); 
console.assert(isURL("http://[email protected]:8080/")); 
console.assert(isURL("http://userid:[email protected]")); 
console.assert(isURL("http://userid:[email protected]/")); 
console.assert(isURL("http://142.42.1.1/")); 
console.assert(isURL("http://142.42.1.1:8080/")); 
console.assert(isURL("http://➡.ws/䨹")); 
console.assert(isURL("http://⌘.ws")); 
console.assert(isURL("http://⌘.ws/")); 
console.assert(isURL("http://foo.com/blah_(wikipedia)#cite-1")); 
console.assert(isURL("http://foo.com/blah_(wikipedia)_blah#cite-1")); 
console.assert(isURL("http://foo.com/unicode_(✪)_in_parens")); 
console.assert(isURL("http://foo.com/(something)?after=parens")); 
console.assert(isURL("http://☺.damowmow.com/")); 
console.assert(isURL("http://code.google.com/events/#&product=browser")); 
console.assert(isURL("http://j.mp")); 
console.assert(isURL("ftp://foo.bar/baz")); 
console.assert(isURL("http://foo.bar/?q=Test%20URL-encoded%20stuff")); 
console.assert(isURL("http://مثال.إختبار")); 
console.assert(isURL("http://例子.測試")); 
console.assert(isURL("http://उदाहरण.परीक्षा")); 
console.assert(isURL("http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com")); 
console.assert(isURL("http://1337.net")); 
console.assert(isURL("http://a.b-c.de")); 
console.assert(isURL("http://223.255.255.254")); 
console.assert(isURL("postgres://u:[email protected]:5702/db")); 
console.assert(isURL("https://[email protected]/13176")); 

//SHOULD NOT MATCH: 
console.assert(!isURL("http://")); 
console.assert(!isURL("http://.")); 
console.assert(!isURL("http://..")); 
console.assert(!isURL("http://../")); 
console.assert(!isURL("http://?")); 
console.assert(!isURL("http://??")); 
console.assert(!isURL("http://??/")); 
console.assert(!isURL("http://#")); 
console.assert(!isURL("http://##")); 
console.assert(!isURL("http://##/")); 
console.assert(!isURL("http://foo.bar?q=Spaces should be encoded")); 
console.assert(!isURL("//")); 
console.assert(!isURL("//a")); 
console.assert(!isURL("///a")); 
console.assert(!isURL("///")); 
console.assert(!isURL("http:///a")); 
console.assert(!isURL("foo.com")); 
console.assert(!isURL("rdar://1234")); 
console.assert(!isURL("h://test")); 
console.assert(!isURL("http:// shouldfail.com")); 
console.assert(!isURL(":// should fail")); 
console.assert(!isURL("http://foo.bar/foo(bar)baz quux")); 
console.assert(!isURL("ftps://foo.bar/")); 
console.assert(!isURL("http://-error-.invalid/")); 
console.assert(!isURL("http://a.b--c.de/")); 
console.assert(!isURL("http://-a.b.co")); 
console.assert(!isURL("http://a.b-.co")); 
console.assert(!isURL("http://0.0.0.0")); 
console.assert(!isURL("http://10.1.1.0")); 
console.assert(!isURL("http://10.1.1.255")); 
console.assert(!isURL("http://224.1.1.1")); 
console.assert(!isURL("http://1.1.1.1.1")); 
console.assert(!isURL("http://123.123.123")); 
console.assert(!isURL("http://3628126748")); 
console.assert(!isURL("http://.www.foo.bar/")); 
console.assert(!isURL("http://www.foo.bar./")); 
console.assert(!isURL("http://.www.foo.bar./")); 
console.assert(!isURL("http://10.1.1.1"));} 

然後測試那串'a's。

相關問題