JavaScript URL 正则怎么写

23,376 阅读2分钟

首先,我们要先了解下什么是 URL,URL 英文全称是 Uniform Resource Locator,直译是统一资源定位器,简称网址,通俗理解就是网络上的门牌号。

图片来自 NodeJS 官网文档截图

通常我们的网址都不包含 auth 这部分,本文示例会忽略掉,URL 的组成如下:

  • protocol://hostname[:port][pathname][?query][#hash](ps: 中括号为可选项)
  • protocol 协议,我们只考虑 http 或 https
  • hostname 主机地址,可以是域名,也可以是 IP 地址

port 端口,http 默认端口是 80,https 默认端口是 443,可以不写

例:s.taobao.com/search?init…

通过上面对 URL 的了解,我们先简单判断下 URL:

function isUrl (url) {
   return /^https?:\/\/.+/.test(url)
}

其中,^ 表示 URL 必须以 h 开头,s? 表示 s 既可以存在,也可以不存在。

然后我们需要对 hostname 做判断,主机地址可以是域名「qq.com」,也可以是 IP「127.0.0.1」,但我们不难发现,不管是域名还是 IP 地址,它们格式都是 xx.xx。所有我们可以先这样改进下正则:

function isUrl (url) {
   return /^https?:\/\/([a-zA-Z0-9]+\.)+[a-zA-Z0-9]+/.test(url)
}

域名可以带符号吗?我去阿里万网验证了下,带连接符 "-" 是可以注册的。

我去查了下资料,域名由各国文字的特定字符集、数字、英文字母及连接符 - 组成,并且 - 不能连续出现,「本文只考虑英文域名」。我们的正则可以再升级下:

function isUrl (url) {
   return /^https?:\/\/(([a-zA-Z0-9]+-?)+[a-zA-Z0-9]+\.)+(([a-zA-Z0-9]+-?)+[a-zA-Z0-9]+)/.test(url)
}

[:port][pathname][?query][#hash] 这些都是可选项:

function isUrl (url) {
   return /^(https?:\/\/(([a-zA-Z0-9]+-?)+[a-zA-Z0-9]+\.)+(([a-zA-Z0-9]+-?)+[a-zA-Z0-9]+))(:\d+)?(\/.*)?(\?.*)?(#.*)?$/.test(url)
}

顶级域名由两组或两组以上的ASCII或各国语言字符构成域名由两组或两组以上的ASCII或各国语言字符构成,现在注册的顶级域名有1000多个,具体可以查看:dnpedia.com/tlds/

本示例中顶级域名只包含英文,所以正则可以改成:

function isUrl (url) {
   return /^(https?:\/\/(([a-zA-Z0-9]+-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+)(:\d+)?(\/.*)?(\?.*)?(#.*)?$/.test(url)
}

完结,撒花。

假如你有更好的写法,欢迎给我留言。