如果我们可以假设 TLD 在字符串的末尾最多有 2 个小节(最后一个小节始终是 TLD 的一部分),并且中间小节的长度在 2 到 3 个字符之间。如果字符串中至少有一个小节不是 TLD,那么以下内容应该与大多数情况匹配。您关于需要所有字母数字且中间有破折号的域的假设是正确的。每个段的长度只能为 63 个字符。
^((?:www\.)?(?:\w[-\w]{0-61}\w|\w)(?:\.\w[-\w]{0-61}\w|\w)*?)\.((?:\w{2-3}\.)?\w+))$
解释一下:
(?: ) 表示非捕获匹配,可以使用 +, *, ?在它上面,但它不会在您的答案中返回
^和$分别匹配字符串的开头和结尾
{n-m} 类似于 * 或 +,但匹配特定数量的字符
*? 表示匹配 0 个或多个匹配,但它是非贪婪的,因此匹配有效匹配所需的最少次数。这意味着可能被正则表达式任一侧匹配的小节将进入 TLD。
(?:www\.)? 这是对短域名(例如 www.un.org)的错误修复
(?:\w[-\w]{0-61}\w|\w) 确保域部分中至少有一个小节,并且每个小节最多 63 个字符 (61+2=63)。小节由外部括号捕获。末尾的 |\w 位解决了 x.org 和 i.net 等单字母域名的边缘情况。
(?:\.\w[-\w]{0-61}\w)*?|\w) 需要重复,因为第一小节不能以点开头。其中零个或多个是必需的,但要使其成为非贪婪搜索。
((?:\w{2-3}\.)?\w+) 根据上述规则匹配 TLD。最后一个小节始终是 TLD 的一部分。关于什么构成二级 TLD 的规则更加模糊
此正则表达式并非完全万无一失,因为有一些例外情况违反了上述规则。 www.un.com 是具有短域名的单段 TLD 的一个示例。 gmp.police.uk(大曼彻斯特警察局)是另一个域的示例,其中 TLD (police.uk) 将无法正确匹配(它将匹配为 uk)。
我已将 TLD 段的长度扩展到 {2-4},因为我们需要包括 .info 和 .mod.uk 等域。我已将第二个 TLD 段的长度减少到 {2-3} 以减少四个字母域名的不匹配数量,对于两个或三个字母的域名我们无能为力,但它们只会在以下情况下不匹配该域还包含一个子域,例如 blog.cat.com
这里列出了一些已在使用的 TLD,其中可能会突出一些边缘情况。我不认为有任何
http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains
http://en.wikipedia.org/wiki/.uk