Javascript URL验证-接受没有协议的URL
我的应用程序中有一个基本的URL验证。现在我正在使用以下代码Javascript URL验证-接受没有协议的URL,javascript,regex,url,Javascript,Regex,Url,我的应用程序中有一个基本的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);
//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使其接受不带协议的URL?使用
(…)使协议可选?
将正则表达式更改为:
/((ftp|http|https):\/\/)?(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
我不是regex专家,但用另一个括号括住协议,并在末尾使用问号,应该可以选择:
function validateUrl(value)
{
var regexp = /((ftp|http|https):\/\/)?(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
return regexp.test(value);
}
将第一部分更改为:
(?:(ftp|http|https):)?(?:\/\/)?
(?:
…)
将在不使用捕获组的情况下对内容进行分组(因此实际协议保留在第一组中)
请注意
协议:
和//
部分是如何单独可选的-因为//www.google.com
是一个有效的(相对)URL。这里有一个用于匹配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`!()\[\]{};:'".,<>?«»“”‘’]))
(2)以下两种:::::::[a-z[a-z[[[[w-[[w-[[[w-[[[[w-[[[w-[[[w-[[[[w-[[w-[[[w-[[[w-[[[[w-[[[[w-[3]以下以下以下以下几种:::::::::::[1,3}[9-z0-9-10-9-10-9-9-9-5-9-9-9-9%[9-9-9-9-9-9-9-9%[3-9[3-9[3-5]以下以下以下以下以下:::::::::::))))))))))以下以下以下以下以下以下以下以下以下以下两两个::::::::::::::::))))以下以下以下以下((((()))))()\[\]{};:“,«»””))
扩展版本(有助于理解):
(?xi)
\b
(#捕获1:完整匹配的URL
(?:
(?:[a-z][\w-]+:)?#URL协议和冒号
(?:
/{1,3}#1-3斜杠
|#或
[a-z0-9%]#单个字母或数字或“%”
#(尝试不匹配,例如“URI::Escape”)
)
|#或
www\d{0,3}[.]#“www.”,“wwww1.”,“www2.”…“www999.”
|#或
[a-z0-9.\-]+[.][a-z]{2,4}/#看起来像是域名后跟斜杠
)
(?:#一个或多个:
[^\s()]+#非空格运行,非-()
|#或
\(([^\s()]+\(\([^\s()]+\)*\)\平衡排列,最多两个级别
)+
(?:#结尾为:
\(([^\s()]+\(\([^\s()]+\)*\)\平衡排列,最多两个级别
|#或
[^\s`!()\[\]{};:“,«»”'''.\n不是空格或这些点状字符之一
)
)
这两个URL都来自,但经过了一些修改,使协议成为可选的—您应该阅读该页面以帮助了解它在做什么,并且它还有一个变体,它只匹配基于web的URL,您可能也需要查看一下。感谢您的回复。很好。您的所有正则表达式都接受@@##$$作为有效URL。有什么想法吗?NLV,你没有指定要我们更正你的正则表达式,你只是问如何更改它以接受任何协议。无论如何,请看下面我的新答案,它给出了一个完整(复杂)的URL验证正则表达式。这将ftp/http/https移动到第2组,并且不接受
//服务器URL。请看我的编辑-现在它接受协议://
或//
或它们都不接受。您还可以使用(?:…)
将组从结果中排除。这仍然过于复杂,而且不适用于http:google.com
(因此,在我的回答中,我只使用了两个可选组)。另外,包装交替的两面的参数是多余的,只会让事情变得更混乱。与hsz的回答一样,这会将ftp/http/https移动到组2,并且不接受//服务器URL。同样,如果这个正则表达式用于捕获URL部分,它会创建不必要的组,它错误地将/
与排除有效URL的协议结合在一起。虽然//google.com有效,但它不是一个有效的URL,我认为大多数人不知道它会起作用,因此从验证中排除此类URL可能非常有用。不是因为它有可能,它必须在每一种形式上都有效。双斜线只是介于两者之间,因为点位于子域、域或TLD之间。双斜线是路径的前缀,而冒号是协议的分隔符-它们是恰好同时出现的两个不同部分。(这在RFC 2396的“3.URI语法组件”中有详细说明)使用//google.com是一个有效的相对Url(同样,请参见RFC 2396的附录“C.1正常示例”),它确实发生在“野外”。不清楚您在那里说什么,这是一个很长的文档-您能参考您所指的特定部分吗?例如,我在Chrome和IE中尝试了://google.com
,但它不起作用,尽管看起来Firefox接受了它。模式设置只包括协议的名称(如“http”,“ftp”),而不包括冒号。所以即使你的正则表达式也不能正确地划分所有的组。但是,由于NLV只想为有效和通用(而不仅仅是工作)URL使用一个验证正则表达式,因此不需要在斜杠周围使用一个组。内部组捕获http
或ftp
的值,或者其他任何值,外部组(冒号所在的位置)不捕获,并且是使整个内容可选的必要条件。类似地,斜杠周围的非捕获组需要使整个事情成为可选的(它可以使用\/{0,2}
,但这将允许/google.com
,这可能是不需要的)。感谢您的努力。让我检查一下。
(?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
)
)