我知道这篇文章有点老了,但这里的所有正则表达式都缺少一个非常重要的组件:对 IDN 域名的支持。
IDN 域名以 xn-- 开头。它们在域名中启用扩展的 UTF-8 字符。例如,您知道“♡.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保留一份已授权的 tld 列表,可用于查看 IDN 域的一些示例。
编辑:
^(((?!\-))(xn\-\-)?[a-z0-9\-_]{0,61}[a-z0-9]{1,1}\.)*(xn\-\-)?([a-z0-9\-]{1,61}|[a-z0-9\-]{1,30})\.[a-z]{2,}$
此正则表达式将停止在主机名末尾带有“-”的域被标记为有效。此外,它允许无限的子域。