这是我的想法,
使用$
锚点从行末开始匹配不是点的任意三个字符。
为了允许类似于.com.au
或.co.nz
类型的域名,字符串末尾的最后一个匹配应该是可选的。
末尾和倒数第二个匹配项都只匹配2-3个字符,以免将其与二级域名混淆。
正则表达式:
[^.]*\.[^.]{2,3}(?:\.[^.]{2,3})?$
演示:
这是一个老问题,随着我们添加新的虚荣顶级域名和更多的国家和地区顶级域名二级域名(例如.co.uk
,.org.uk
),挑战变得更加复杂。以至于正则表达式几乎肯定会返回错误的结果。
唯一可靠地获取主机名的方法是调用知道它们的服务(例如Public Suffix List)。
有几个开源库可供使用,例如psl,也可以编写自己的库。
psl
的用法非常直观。从他们的文档中:
var psl = require('psl');
// Parse domain without subdomain
var parsed = psl.parse('google.com');
console.log(parsed.tld); // 'com'
console.log(parsed.sld); // 'google'
console.log(parsed.domain); // 'google.com'
console.log(parsed.subdomain); // null
// Parse domain with subdomain
var parsed = psl.parse('www.google.com');
console.log(parsed.tld); // 'com'
console.log(parsed.sld); // 'google'
console.log(parsed.domain); // 'google.com'
console.log(parsed.subdomain); // 'www'
// Parse domain with nested subdomains
var parsed = psl.parse('a.b.c.d.foo.com');
console.log(parsed.tld); // 'com'
console.log(parsed.sld); // 'foo'
console.log(parsed.domain); // 'foo.com'
console.log(parsed.subdomain); // 'a.b.c.d'
旧回答
您可以使用这个:
(\w+\.\w+)$
缺乏更多细节(例如样本文件,您正在使用的语言),很难确定这是否有效。
^(?:https?:\/\/)(?:w{3}\.)?.*?([^.\r\n\/]+\.)([^.\r\n\/]+\.[^.\r\n\/]{2,6}(?:\.[^.\r\n\/]{2,6})?).*$
并且添加尽可能多的捕获组,以捕获URL的组件。
如果您希望简化/修改/探索表达式,则已在regex101.com的右上面板上进行了解释。如果您愿意,您还可以在此链接中观看如何匹配一些示例输入。
jex.im可将正则表达式可视化:
如果你正在使用 JavaScript 并希望一种简单的方法来提取顶级和二级域名,我最终采用了以下方式:
'example.aus.com'.match(/\.\w{2,3}\b/g).join('')
以下是一些示例输出:
'example.aus.com' // .aus.com
'example.austin.com' // .austin.com
'example.aus.com/howdy' // .aus.com
'example.co.uk/howdy' // .co.uk
'example.aus.com'.match(/\.\w*\b/g).join('')
[RegularExpression("^(https?:\\/\\/)?(([\\w]+)?\\.?(\\w+\\.((za|zappos|zara|zero|zip|zippo|zm|zone|zuerich|zw))))\\/?$", ErrorMessage = "Is not a valid fully-qualified URL.")]
您也可以从此链接中添加更多的域名:
由于顶级域现在包括像.wang和.travel这样超过三个字符的内容,这里有一个正则表达式可以满足这些新TLD:
([^.\s]+\.[^.\s]+)$
let hostname = 'test.something.else.be';
let domain = hostname.replace(/^.+\.([^\.]+\.[^\.]+)$/, '$1');
document.write(domain);
这将导致一个包含'else.com'
的字符串。这是因为正则表达式本身将匹配完整的字符串,并且捕获组将映射到$1
。因此,它用'$1'
(实际上是'else.com'
)替换了完整的字符串'test.something.else.com'
。
这个正则表达式并不漂亮,可能可以通过使用像{3}
这样的东西来定义你想要查找子域的深度,但这只是一个示例。
(?:\w+:\/{2})?(?<cs_domain>(?<cs_domain_sub>(?:[\w\-]+\.)*?)(?<cs_domain_root>[\w\-]+(?<cs_domain_tld>(?:\.\w{2})?(?:\.\w{2,3}|\.xn-+\w+|\.site|\.club))))\|
很难说它是否完美,但它可以在我测试的所有数据集上运行,包括.club、.xn-1234、.co.uk和其他奇怪的结尾。而且它只需要5556步就能处理40k个字符的日志,因此效率似乎也是合理的。
/\.(?:nl|se|no|es|milru|fr|es|uk|ca|de|jp|au|us|ch|it|io|org|com|net|int|edu|mil|arpa)/
基于http://www.seobythesea.com/2006/01/googles-most-popular-and-least-popular-top-level-domains/。