我知道这是一个有点老的帖子,但是所有的正则表达式都缺少一个非常重要的组件:支持IDN域名。
IDN域名 以xn--开头。它们允许在域名中使用扩展的UTF-8字符。例如,你知道“♡.com”是一个有效的域名吗?是的,“爱心点com”!为了验证域名,你需要让http://xn--c6h.com/通过验证。
请注意,要使用这个正则表达式,你需要将域名转换为小写,并使用一个IDN库来确保你将域名编码为ACE(也称为“ASCII兼容编码”)。一个好的库是GNU-Libidn。
idn(1) 是国际化域名库的命令行接口。以下示例将UTF-8格式下的主机名转换为ACE编码形式。生成的URL https://nic.xn--flw351e/ 就可以用作https://nic.谷歌/的ACE编码等价物。
$ idn --quiet -a nic.谷歌
nic.xn--flw351e
这个神奇的正则表达式应该覆盖了 大部分 域名(虽然,我确信还有很多我没有考虑到的有效特殊情况):
^((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,1}\.(xn--)?([a-z0-9\-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})$
在选择域验证正则表达式时,您应该查看域是否匹配以下内容:
- xn--stackoverflow.com
- stackoverflow.xn--com
- stackoverflow.co.uk
如果这三个域名没有通过,你的正则表达式可能不允许合法的域名!
请查看
Oracle国际语言环境指南中的国际化域名支持页面以获取更多信息。
可以在这里尝试使用正则表达式:
http://www.regexr.com/3abjr
ICANN保留了
已授权的顶级域名列表,其中可用于查看一些IDN域名的示例。
编辑:
^(((?!-))(xn--|_)?[a-z0-9-]{0,61}[a-z0-9]{1,1}\.)*(xn--)?([a-z0-9][a-z0-9\-]{0,60}|[a-z0-9-]{1,30}\.[a-z]{2,})$
这个正则表达式将阻止以'-'结尾的主机名域被标记为有效。此外,它允许无限子域。