2010-08-03 73 views
5

我在我的应用程序中进行了基本的URL验证。现在我使用下面的代码。网址验证 - 接受没有协议的网址

//validates whether the given value is 
//a valid URL 
function validateUrl(value) 
{ 
    var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ 
    return regexp.test(value); 
} 

但现在它不接受没有协议的URL。例如。如果我提供www.google.com它不接受它。我如何修改RegEx以使其接受没有协议的网址?

+0

感谢您对您的所有答复。工作很好。 – NLV 2010-08-03 12:24:53

+0

你所有的正则表达式都接受@@ ## $$作为有效的URL。有任何想法吗? – NLV 2010-08-04 06:49:06

+0

NLV,你没有指定你希望我们纠正你的正则表达式,你只是问如何改变它来接受任何协议。 无论如何,请参阅下面我的新答案,它给出了一个完整的(和复杂的)URL验证正则表达式。 – 2010-08-06 20:00:05

回答

5

下面是匹配URL一个很长的正则表达式:

(?i)\b((?:(?:[a-z][\w-]+:)?(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’])) 

的,扩大的版本(以帮助它理解):

(?xi) 
\b 
(       # Capture 1: entire matched URL 
    (?: 
    (?:[a-z][\w-]+:)?    # URL protocol and colon 
    (?: 
     /{1,3}      # 1-3 slashes 
     |        # or 
     [a-z0-9%]      # Single letter or digit or '%' 
            # (Trying not to match e.g. "URI::Escape") 
    ) 
    |       # or 
    www\d{0,3}[.]    # "www.", "www1.", "www2." … "www999." 
    |       # or 
    [a-z0-9.\-]+[.][a-z]{2,4}/ # looks like domain name followed by a slash 
) 
    (?:       # One or more: 
    [^\s()<>]+      # Run of non-space, non-()<> 
    |        # or 
    \(([^\s()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels 
)+ 
    (?:       # End with: 
    \(([^\s()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels 
    |         # or 
    [^\s`!()\[\]{};:'".,<>?«»“”‘’]  # not a space or one of these punct chars 
) 
) 

这些都来自this page,但略作修改为了使协议正确可选 - 您应该阅读该页面以帮助了解它在做什么,并且它还有一个只与基于Web的URL匹配的变体,您可能也需要查看它。

+0

感谢您的努力。让我对它进行检查。 – NLV 2010-08-07 08:49:46

+2

chrome console出错 – 2014-06-05 17:53:23

1

制作协议可选的(...)?

/(((ftp|http|https):\/\/)|(\/\/))?(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ 
+0

这会将ftp/http/https移至第2组,并且不接受“//服务器”URL。 – 2010-08-03 12:26:20

+0

看看我的编辑 - 现在它接受'protocol://'或'//'或者它们都不是。 – hsz 2010-08-03 12:37:57

+0

您也可以使用'(?:...)'从结果中排除组。 – hsz 2010-08-03 12:38:54

1

变化的正则表达式:

/((ftp|http|https):\/\/)?(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ 
+0

与hsz的回答一样,这会将ftp/http/https移至第2组,并且不接受“//服务器”URL。 – 2010-08-03 12:26:48

1

我不是一个正则表达式的专家,但围绕着与另一架协议,并在最后用一个问号应使其成为可选项:

function validateUrl(value) 
{ 
    var regexp = /((ftp|http|https):\/\/)?(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ 
    return regexp.test(value); 
} 
+0

同样,如果这个正则表达式被用来捕获URL部分,它会创建不必要的组,并且它不正确地将'//'与协议相结合,这会排除有效的URL。 – 2010-08-03 12:28:36

+0

尽管//google.com有效,但它不是一个有效的网址,我不认为大多数人知道它会起作用,因此从验证中排除此类网址可能非常有用。不是因为它有可能必须在每种形式中都有效。由于点在子域,域或顶级域名之间,所以双斜杠只是介于两者之间。 – 2ndkauboy 2010-08-03 14:22:49

+0

双斜杠是路径的前缀,而冒号是协议的分隔符 - 它们是恰好偶然发生的两个不同部分。 (这在RFC 2396的“3. URI语法组件”中有详细说明) 使用//google.com是一个有效的相对Url(同样,请参阅RFC 2396的附录“C.1正常示例”),它确实发生“在野外”。 – 2010-08-03 15:00:49

0

将第一部分更改为:

(?:(ftp|http|https):)?(?:\/\/)? 

而不使用捕获组的(?: ... )意愿基含量(因此实际协议保持在第一组)。

请注意,protocol://部件是单独可选的 - 因为//www.google.com是有效的(相对)URL。

+0

冒号不依赖于协议:http://tools.ietf.org/html/rfc2396 – 2ndkauboy 2010-08-03 14:26:40

+0

不清楚你在那里说什么,这是一个很长的文档 - 你可以参考你指的特定部分至?我尝试过(例如)Chrome和IE中的':// google.com',但它不起作用,尽管它看起来像Firefox接受它。 – 2010-08-03 14:54:17

+0

模式选项只包括协议的名称(如'http','ftp'),但不包括冒号。所以即使你的正则表达式也不能正确地分割所有的组。但是,由于NLV只想为有效和普通(而不仅仅是工作)的URL提供验证正则表达式,因此不需要在斜线周围使用组。 – 2ndkauboy 2010-08-03 15:25:30

-1
+1

请注意,[link-only answers](http://meta.stackoverflow.com/tags/link-only-answers/info)不鼓励,SO答案应该是搜索的终点寻求一种解决方案(而另一种参考文献的中途停留时间往往会随着时间的推移而变得陈旧)。请考虑在此添加独立的摘要,并将链接保留为参考。 – kleopatra 2013-12-05 11:42:49