2013-11-01 30 views
10

uzyskać adres URL w następujący sposób:Szczegółowe subdomenę z adresu URL w foo.bar.car.com

foo.bar.car.com.au

muszę wyodrębnić foo.bar.

natknąłem się na następujący kod:

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;  
} 

Daje mi jak foo.bar.car. Chcę foo.bar. Czy powinienem użyć podziału i wziąć 0 i 1?

Ale wtedy jest możliwe wwww.

Czy istnieje prosty sposób na to?

+0

Po pierwsze, utrzymajmy język w czystości. Ale po drugie, zapominając o kodzie, skąd wiadomo, że 'foo.bar' jest subdomeną w' foo.bar.car.com.au'? –

+0

Przepraszam za ten język. To musi być amerykańskie. Wiem, ponieważ go rozwijam. – DarthVader

+0

Pytanie nie brzmi: jak ty, @DarthVader. Pytanie brzmi: co może założyć kod? Zobacz moją odpowiedź poniżej .. –

Odpowiedz

10

Ze względu na wymagania (chcesz 1st dwa poziomy, nie wliczając 'www.') Chciałbym podejść do niego coś takiego:

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; 
} 
1

Polecam używanie wyrażenia regularnego. Poniższy fragment kodu powinien wyodrębnić to, czego szukasz ...

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

OK, po pierwsze. Czy szukasz konkretnie w "com.au", czy też są to ogólne nazwy domen internetowych? Ponieważ, jeśli jest to drugie, po prostu nie ma automatycznego sposobu określania, ile domeny to "witryna" lub "strefa" lub jakikolwiek inny i jaki jest indywidualny "host" lub inny rekord w tej strefie.

Jeśli musisz mieć możliwość znalezienia tego na podstawie dowolnej nazwy domeny, zechcesz pobrać listę TLD z projektu końcowego Suita Mozilla (http://publicsuffix.org) i użyć ich algorytmu do znalezienia domeny TLD w nazwie domeny . Następnie możesz założyć, że część, którą chcesz, kończy się ostatnią etykietą tuż przed TLD.

+0

Jest to o wiele bardziej poprawne niż moja odpowiedź z punktu widzenia "solidnego kodu". Jeśli wiesz, że ZAWSZE chcesz mieć tylko dwa pierwsze poziomy, mój będzie działał (jako punkt wyjścia), ale ogólnie jest lepszy. – AllenG

2
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; 
} 
5

wychodził podobny problem i na podstawie poprzednie odpowiedzi, napisałem tę metodę rozszerzenia. Co najważniejsze, przyjmuje parametr, który definiuje domenę "root", tj. Cokolwiek konsument danej metody uważa za root. W przypadku PO za, rozmowa byłaby

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

Oto metoda rozszerzenie:

/// <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; 
} 
+0

Jeśli masz problem z pisaniem metody rozszerzenia, dlaczego nie rozszerzyć łańcucha 'System.Uri' zamiast łańcucha? Następnie ma odpowiedni kontekst związany z adresem URL. –

+0

@TrueBlueAussie Rzeczywiście. Rozszerzyłem string, ponieważ był to MVP dla mojej bazy kodów. Przyszłe refaktoryzowanie prawdopodobnie doprowadziłoby do rozszerzenia System.Uri, aby zachować kontekst, jak sugerujesz. – HeyZiko

4

Można użyć następujący pakiet Nuget Nager.PublicSuffix.

PM> Install-Package Nager.PublicSuffix 

Przykład

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"; 
0

Poza pakietem Nuget Nager.PubilcSuffix określonego w this answer, jest również opakowanie Nuget Louw.PublicSuffix, który zgodnie z jego GitHub project page jest Net Rdzeń biblioteki, które analizuje Public Suffix i jest oparty na Nager.PublicSuffix project, z następującymi zmianami:

  • Przeniesiono do biblioteki .NET Core.
  • Naprawiono bibliotekę, dzięki czemu przechodzi WSZYSTKIE kompleksowe testy.
  • Refaktoryzowane klasy w celu podzielenia funkcjonalności na mniejsze skupione klasy.
  • Wykonane klasy niezmienne. Tak więc DomainParser może być używany jako singleton i jest bezpieczny dla wątków.
  • Dodano WebTldRuleProvider i FileTldRuleProvider.
  • Dodano funkcję sprawdzania, czy reguła była regułą ICANN lub domeny prywatnej.
  • Zastosowanie programowania asynchronicznego modelu

strona stwierdza również, że wiele z powyższych zmian zostały przekazane z powrotem do pierwotnego Nager.PublicSuffix project.