2010-11-08 17 views
5

Diese Frage hat Antwort in anderen Sprachen/Plattformen, aber ich konnte keine robuste Lösung in C# finden. Hier suche ich für den Teil der URL, die wir in WHOIS verwenden, so bin ich nicht daran interessiert, in Sub-Domains, Port, Schema usw.Domain Name aus URL in C# extrahieren

Example 1: http://s1.website.co.uk/folder/querystring?key=value => website.co.uk 
Example 2: ftp://username:[email protected] => website.com 

Das Ergebnis sollte gleich sein, wenn der Eigentümer in whois ist das selbe, also gehören sub1.xyz.com und sub2.xyz.com beide dazu, wer die xyz.com hat, die ich von einer URL extrahieren muss.

Antwort

6

Ich brauchte das gleiche, also schrieb ich eine Klasse, die Sie kopieren und in Ihre Lösung einfügen können. Es verwendet ein hart codiertes String-Array von Tlds. http://pastebin.com/raw.php?i=VY3DCNhp

Console.WriteLine(GetDomain.GetDomainFromUrl("http://www.beta.microsoft.com/path/page.htm")); 

Ausgänge microsoft.com

und

Console.WriteLine(GetDomain.GetDomainFromUrl("http://www.beta.microsoft.co.uk/path/page.htm")); 

Ausgänge microsoft.co.uk

+0

Vielen Dank für Ihre Arbeit. Ein weiteres Problem besteht darin, die Liste auf dem neuesten Stand zu halten, aber ich denke nicht, dass sie sich sehr häufig ändert. – Xaqron

+0

Diese Klasse ist großartig. Ich habe eine Complete-Liste aller TLDs von [der PublicSuffix-Liste] (http://publicssuffix.org/list/), aktualisiert für heute, erstellt. Es ist fast doppelt so groß wie das, das Sie eingereicht haben (~ 6390 Einträge). Sie finden die Variable unter http://pastebin.com/raw.php?i=PxKWw5jt, falls Sie sie jemals brauchen sollten. :) Vielen Dank noch mal! :) – moskalak

1

Am nächsten kommt die System.Uri.Host-Eigenschaft, die den Abschnitt sub1.xyz.com extrahiert. Leider ist es schwer zu wissen, was genau der "Toplevel" Teil des Hosts ist (zB sub1.foo.co.uk versus sub1.xyz.com)

+0

es ist fast unmöglich, sicher zu wissen, welche die Top-Level ist, weil zum Beispiel .co.uk zwei Teile erfordert, aber .info oder .jp erfordern etwas anderes als '. [a-zA-Z] {3}' – jcolebrand

+0

Die [Liste der öffentlichen Suffixe] (http: // publicssuffi x.org/) kann für diese Art von Aufgabe verwendet werden. Aber es ist wahrscheinlich am einfachsten, den ganzen Hostnamen zu "bearbeiten" und ein Segment nach dem anderen zu bearbeiten, bis Sie Ergebnisse erhalten. – bobince

+0

Diese Liste "sollte" stimmen, aber das ist mein Punkt. "sollte" ist keine großartige Geschäftsregel ... – jcolebrand

3

Wie @Pete bemerkte, ist dies ein bisschen kompliziert, aber Ich werde es versuchen.

Beachten Sie, dass diese Anwendung eine vollständige Liste bekannter TLDs enthalten muss. Diese können von http://publicsuffix.org/ abgerufen werden. Links Extrahieren der Liste von dieser Site als Übung für den Leser.

class Program 
{ 
    static void Main(string[] args) 
    { 
     var testCases = new[] 
     { 
      "www.domain.com.ac", 
      "www.domain.ac", 
      "domain.com.ac", 
      "domain.ac", 
      "localdomain", 
      "localdomain.local" 
     }; 

     foreach (string testCase in testCases) 
     { 
      Console.WriteLine("{0} => {1}", testCase, UriHelper.GetDomainFromUri(new Uri("http://" + testCase + "/"))); 
     } 

     /* Produces the following results: 

      www.domain.com.ac => domain.com.ac 
      www.domain.ac => domain.ac 
      domain.com.ac => domain.com.ac 
      domain.ac => domain.ac 
      localdomain => localdomain 
      localdomain.local => localdomain.local 
     */ 
    } 
} 

public static class UriHelper 
{ 
    private static HashSet<string> _tlds; 

    static UriHelper() 
    { 
     _tlds = new HashSet<string> 
     { 
      "com.ac", 
      "edu.ac", 
      "gov.ac", 
      "net.ac", 
      "mil.ac", 
      "org.ac", 
      "ac" 

      // Complete this list from http://publicsuffix.org/. 
     }; 
    } 

    public static string GetDomainFromUri(Uri uri) 
    { 
     return GetDomainFromHostName(uri.Host); 
    } 

    public static string GetDomainFromHostName(string hostName) 
    { 
     string[] hostNameParts = hostName.Split('.'); 

     if (hostNameParts.Length == 1) 
      return hostNameParts[0]; 

     int matchingParts = FindMatchingParts(hostNameParts, 1); 

     return GetPartOfHostName(hostNameParts, hostNameParts.Length - matchingParts); 
    } 

    private static int FindMatchingParts(string[] hostNameParts, int offset) 
    { 
     if (offset == hostNameParts.Length) 
      return hostNameParts.Length; 

     string domain = GetPartOfHostName(hostNameParts, offset); 

     if (_tlds.Contains(domain.ToLowerInvariant())) 
      return (hostNameParts.Length - offset) + 1; 

     return FindMatchingParts(hostNameParts, offset + 1); 
    } 

    private static string GetPartOfHostName(string[] hostNameParts, int offset) 
    { 
     var sb = new StringBuilder(); 

     for (int i = offset; i < hostNameParts.Length; i++) 
     { 
      if (sb.Length > 0) 
       sb.Append('.'); 

      sb.Append(hostNameParts[i]); 
     } 

     string domain = sb.ToString(); 
     return domain; 
    } 
} 
+0

ein Text fehlt – Xaqron

+0

@Xaqron - Ich sehe nicht wie. Ich habe den gesamten Code in ein neues Konsolenprojekt kopiert und es kompiliert korrekt und gibt die erwarteten Ergebnisse. Könnten Sie bitte genauer auf das eingehen, was Ihrer Meinung nach fehlt? –

+0

Es fehlte der Spaß unter GetDomainFromHostName() Methode, aber es ist jetzt da. Vielen Dank. – Xaqron

0

wenn Sie Domainnamen benötigen, dann können Sie URi.hostadress in .net

verwenden, wenn Sie die URL von Inhalten benötigen, dann müssen Sie sie Regex analysieren.