解析字符串以获取域名/主机名

7
我们的客户可以通过域名进入网站,也可以通过联系人输入邮件地址。
现在我们需要找到那些网站域名能与邮件地址的域名相关联的客户。
所以我的想法是提取网址和URL中的主机,并进行比较。
那么获取URL中主机名最可靠的算法是什么?
例如,主机名可以是:
foo.com
www.foo.com
http://foo.com
https://foo.com
https://www.foo.com

结果应始终为foo.com。

澄清一下,由于您删除了带有.vu顶级域名的示例,您是在说您只关心.com顶级域名,还是这只是一种过度简化? - Mike Pennington
这只是一种过于简单化的说法。它可以是任何类型的顶级域名,如.de、.eu、.biz等等......重要的要求是通过查看网站URL来找到可能与邮件地址匹配的候选者。 - Boas Enkler
4个回答

15

不要依靠不可靠的正则表达式,使用System.Uri来完成解析。可以使用以下代码:

string uriStr = "www.foo.com";
if (!uriStr.Contains(Uri.SchemeDelimiter)) {
    uriStr = string.Concat(Uri.UriSchemeHttp, Uri.SchemeDelimiter, uriStr);
}
Uri uri = new Uri(uriStr);
string domain = uri.Host; // will return www.foo.com

现在如果只需要顶级域名,你可以使用以下方法:

string tld = uri.GetLeftPart( UriPartial.Authority ); // will return foo.com

3
域名后缀不应该只是"com"吗? - mikesjawnbit
3
@anubhava说,uri.GetLeftPart(UriPartial.Authority)不能返回根域名,而是返回整个左侧URL的部分,从方案开始到端口结束(如果指定)。据我所知,忽略主机的子域名部分的唯一方法是使用两次string.LastIndexOf()显式截断它。 - Tim Coulter
1
我可以确认(至少在aspnetcore 3.1中),字符串tld = uri.GetLeftPart(UriPartial.Authority); // 在这里不会返回foo.com,它将返回www.foo.com(非www子域名同样如此)。 - MemeDeveloper

1
这是一个正则表达式,可以匹配您提供的URL。基本上,http和https等都是可选的,www也是如此。然后将所有内容与可能的路径匹配起来。
var expression = /(https?:\/\/)?(www\.)?([^\/]*)(\/.*)?$/;

这意味着:
var result = 'https://www.foo.com.vu/blah'.replace(expression, '$3')

将被评估为

result === 'foo.com.vu'

问题是关于子域名的。我认为它们不应该包含在结果中。所以,product.mycompany.com 应该在 mycompany.com 中结束。 - Boas Enkler
1
这可能会相当困难,因为您无法计算点以娱乐子域(我想我试图说的是像.co.uk这样的东西会搞砸一切)。您可能需要进行两个检查,一个使用上面的表达式,另一个则剥离第一个点之前的字符。 - cmilhench
如果您评估具有无效字符的DNS名称(例如a!notit.com)或具有太多字符(超过63个字符),则此答案将失败。 - Mike Pennington

1

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接