2010-11-08 24 views
5

Questa domanda ha risposta in altre lingue/piattaforme ma non sono riuscito a trovare una soluzione valida in C#. Qui sto cercando la parte dell'URL che usiamo in WHOIS quindi non sono interessato a sottodomini, porto, schema, eccEstrarre il nome di dominio dall'UR in C#

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

Il risultato dovrebbe essere lo stesso quando il proprietario in whois è lo stesso quindi sub1.xyz.com e sub2.xyz.com appartengono entrambi a chi ha il xyz.com che ho bisogno di estrarre da un URL.

risposta

6

Mi serviva lo stesso, così ho scritto una classe che è possibile copiare e incollare nella soluzione. Usa una serie di stringhe hard coded di tld. http://pastebin.com/raw.php?i=VY3DCNhp

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

uscite microsoft.com

e

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

uscite microsoft.co.uk

+0

Grazie per aver condiviso il tuo lavoro. Un altro problema è mantenere aggiornato l'elenco ma non penso che cambi molto frequentemente. – Xaqron

+0

Questa classe è fantastica. Ho incluso un elenco completo di tutti i TLD da [l'elenco PublicSuffix] (http://publicsuffix.org/list/), aggiornato per oggi. È quasi il doppio di quello che hai inviato (~ 6390 voci) Puoi trovare la variabile su http://pastebin.com/raw.php?i=PxKWw5jt, nel caso tu ne abbia bisogno. :) Grazie ancora! :) – moskalak

1

Il più vicino possibile è la proprietà System.Uri.Host, che estrae la parte sub1.xyz.com. Sfortunatamente, è difficile sapere quale sia esattamente la porzione "toplevel" dell'host (ad esempio sub1.foo.co.uk versus sub1.xyz.com)

+0

è quasi impossibile sapere con certezza che è il primo livello, perché ad esempio .co.uk richiede due parti, ma .info o .jp richiedono qualcosa di diverso da '. [a-zA-Z] {3}' – jcolebrand

+0

The [Public Suffix List] (http: // publicsuffi x.org/) può essere usato per questo tipo di compito. Ma probabilmente è più facile solo per 'whois' l'intero nome host e lavorare su un segmento alla volta fino ad ottenere risultati. – bobince

+0

L'elenco "dovrebbe" avere ragione, ma questo è il mio punto. "should" non è una grande regola aziendale ... – jcolebrand

3

Come notato da @Pete, questo è un po 'complicato, ma Lo proverò.

Si noti che questa applicazione deve contenere un elenco completo di TLD noti. Questi possono essere recuperati da http://publicsuffix.org/. A sinistra estrarre la lista da questo sito come esercizio per il lettore.

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

manca del testo – Xaqron

+0

@Xaqron - Non vedo come. Ho copiato l'intero codice in un nuovo progetto di console e viene compilato correttamente e fornisce i risultati previsti. Potresti essere più specifico su ciò che credi che manchi? –

+0

Mancava il jest sotto il metodo GetDomainFromHostName(), ma ora è lì. Grazie. – Xaqron

0

se avete bisogno di nome di dominio, è possibile utilizzare URi.hostadress in .net

se è necessario l'URL dal contenuto di allora avete bisogno di analizzare utilizzando espressioni regolari.