从 foo.bar.car.com 中的 URL 获取特定子域



给定一个URL,如下所示:

foo.bar.car.com.au

我需要提取foo.bar.

我遇到了以下代码:

private static string GetSubDomain(Uri url)
{
    if (url.HostNameType == UriHostNameType.Dns)
    {
        string host = url.Host;
        if (host.Split('.').Length > 2)
        {
            int lastIndex = host.LastIndexOf(".");
            int index = host.LastIndexOf(".", lastIndex - 1);
            return host.Substring(0, index);
        }
    }         
    return null;     
}

这给了我喜欢foo.bar.car.我要 foo.bar。我应该只使用 split 并取 0 和 1 吗?

但是有可能wwww。

有没有简单的方法?

根据您的要求(您需要第一个两个级别,不包括"www.")我会这样处理它:

private static string GetSubDomain(Uri url)
{
    if (url.HostNameType == UriHostNameType.Dns)
    {
        string host = url.Host;
        var nodes = host.Split('.');
        int startNode = 0;
        if(nodes[0] == "www") startNode = 1;
        return string.Format("{0}.{1}", nodes[startNode], nodes[startNode + 1]);
    }
    return null; 
}

我遇到了类似的问题,并根据前面的答案编写了这个扩展方法。 最重要的是,它需要一个定义"根"域的参数,即该方法的使用者认为是根的任何内容。 在OP的情况下,调用将是

Uri uri = "foo.bar.car.com.au";
uri.DnsSafeHost.GetSubdomain("car.com.au"); // returns foo.bar
uri.DnsSafeHost.GetSubdomain(); // returns foo.bar.car

下面是扩展方法:

/// <summary>Gets the subdomain portion of a url, given a known "root" domain</summary>
public static string GetSubdomain(this string url, string domain = null)
{
  var subdomain = url;
  if(subdomain != null)
  {
    if(domain == null)
    {
      // Since we were not provided with a known domain, assume that second-to-last period divides the subdomain from the domain.
      var nodes = url.Split('.');
      var lastNodeIndex = nodes.Length - 1;
      if(lastNodeIndex > 0)
        domain = nodes[lastNodeIndex-1] + "." + nodes[lastNodeIndex];
    }
    // Verify that what we think is the domain is truly the ending of the hostname... otherwise we're hooped.
    if (!subdomain.EndsWith(domain))
      throw new ArgumentException("Site was not loaded from the expected domain");
    // Quash the domain portion, which should leave us with the subdomain and a trailing dot IF there is a subdomain.
    subdomain = subdomain.Replace(domain, "");
    // Check if we have anything left.  If we don't, there was no subdomain, the request was directly to the root domain:
    if (string.IsNullOrWhiteSpace(subdomain))
      return null;
    // Quash any trailing periods
    subdomain = subdomain.TrimEnd(new[] {'.'});
  }
  return subdomain;
}
您可以使用

以下 nuget 包 Nager.PublicSuffix。它使用来自Mozilla的PUBLIC SUFFIX LIST来拆分域。

PM> Install-Package Nager.PublicSuffix

 var domainParser = new DomainParser();
 var data = await domainParser.LoadDataAsync();
 var tldRules = domainParser.ParseRules(data);
 domainParser.AddRules(tldRules);
 var domainName = domainParser.Get("sub.test.co.uk");
 //domainName.Domain = "test";
 //domainName.Hostname = "sub.test.co.uk";
 //domainName.RegistrableDomain = "test.co.uk";
 //domainName.SubDomain = "sub";
 //domainName.TLD = "co.uk";
private static string GetSubDomain(Uri url)
{
    if (url.HostNameType == UriHostNameType.Dns)
    {
        string host = url.Host;   
        String[] subDomains = host.Split('.');
        return subDomains[0] + "." + subDomains[1];
     }
    return null; 
}

好的,首先。 您是专门在"com.au"中查找,还是这些通用的互联网域名? 因为如果是后者,则根本无法自动确定域中有多少是"站点"或"区域"或其他内容,以及该区域内的单个"主机"或其他记录的数量。

如果您需要能够从任意域名中找出这一点,您将需要从 Mozilla 公共后缀项目 (http://publicsuffix.org) 中获取 TLD 列表,并使用他们的算法在您的域名中查找 TLD。 然后,您可以假设您想要的部分以紧邻 TLD 之前的最后一个标签结尾。

我建议使用正则表达式。以下代码片段应提取您要查找的内容...

string input = "foo.bar.car.com.au";
var match = Regex.Match(input, @"^w*.w*.w*");
var output = match.Value;

除了本答案中指定的NuGet Nager.PubilcSuffix包外,还有NuGet Louw.PublicSuffix包,根据其GitHub项目页面,它是一个解析公共后缀的.Net Core库,并且基于Nager.PublicSuffix项目,具有以下更改:

  • 移植到 .NET Core 库。
  • 修复了库,因此它通过了所有综合测试。
  • 重构类以将功能拆分为较小的重点类。
  • 使类不可变。因此DomainParser可以用作单例并且是线程安全的。
  • 添加了WebTldRuleProviderFileTldRuleProvider
  • 添加了了解规则是 ICANN 规则还是私有域规则的功能。
  • 使用异步编程模型

该页面还指出,上述许多更改已提交回原始Nager.PublicSuffix项目。

最新更新