Ответ 1
Да, можно использовать:
Uri.GetLeftPart( UriPartial.Authority )
Я пытаюсь извлечь только имя домена из строки URL. У меня почти есть... Я использую URI
У меня есть строка. Моя первая мысль заключалась в использовании Regex, но потом я решил использовать класс URI
Мне нужно преобразовать вышеперечисленное в google.com и google без www
Я сделал следующее
Uri test = new Uri(referrer);
log.Info("Domain part : " + test.Host);
В основном это возвращает www.google.com.... Я бы хотел попробовать и вернуть 2 формы, если это возможно... как упоминалось...
google.com и google
Возможно ли это с URI?
Да, можно использовать:
Uri.GetLeftPart( UriPartial.Authority )
@Dewfy: ошибка заключается в том, что ваш метод возвращает "uk" для "www.test.co.uk", но в этом домене явно "test.co.uk".
@naivists: ошибка заключается в том, что ваш метод возвращает "beta.microsoft.com" для "www.beta.microsoft.com", но здесь домен явно "microsoft.com"
Мне нужно то же самое, поэтому я написал класс, который вы можете скопировать и вставить в свое решение. Он использует строковый массив строк tld. http://pastebin.com/raw.php?i=VY3DCNhp
Console.WriteLine(GetDomain.GetDomainFromUrl("http://www.beta.microsoft.com/path/page.htm"));
выходы microsoft.com
и
Console.WriteLine(GetDomain.GetDomainFromUrl("http://www.beta.microsoft.co.uk/path/page.htm"));
выходы microsoft.co.uk
google.com не гарантирует, что он будет таким же, как www.google.com(ну, для этого примера это технически, но может быть иначе).
Возможно, вам нужно удалить домен верхнего уровня и поддомену "www"? Затем просто split('.')
и возьмите часть перед последней частью!
Ниже приведен код, который даст только расширение SLD плюс gTLD или ccTLD (обратите внимание на исключение ниже). Я не забочусь о DNS.
Теория такова:
Что касается кода, короткого и сладкого:
private static string GetDomainName(string url)
{
string domain = new Uri(url).DnsSafeHost.ToLower();
var tokens = domain.Split('.');
if (tokens.Length > 2)
{
//Add only second level exceptions to the < 3 rule here
string[] exceptions = { "info", "firm", "name", "com", "biz", "gen", "ltd", "web", "net", "pro", "org" };
var validTokens = 2 + ((tokens[tokens.Length - 2].Length < 3 || exceptions.Contains(tokens[tokens.Length - 2])) ? 1 : 0);
domain = string.Join(".", tokens, tokens.Length - validTokens, validTokens);
}
return domain;
}
Очевидным исключением является то, что это не будет касаться двухбуквенных доменных имен. Поэтому, если вам повезло, что вы владеете ab.com, вам нужно немного адаптировать код. Для нас простых смертных этот код будет охватывать почти каждый рДВУ и ccTLD, за вычетом нескольких очень экзотических.
Я пробовал практически каждый подход, но все они не соответствовали желаемому результату. Итак, вот мой подход скорректирован с servermanfail.
Файл tld доступен на https://publicsuffix.org/list/ Я взял файл из https://publicsuffix.org/list/effective_tld_names.dat, проанализировав его и выполнив поиск tld. Если новый tld опубликован, просто загрузите последний файл.
получайте удовольствие.
using System;
using System.Collections.Generic;
using System.IO;
namespace SearchWebsite
{
internal class NetDomain
{
static public string GetDomainFromUrl(string Url)
{
return GetDomainFromUrl(new Uri(Url));
}
static public string GetDomainFromUrl(string Url, bool Strict)
{
return GetDomainFromUrl(new Uri(Url), Strict);
}
static public string GetDomainFromUrl(Uri Url)
{
return GetDomainFromUrl(Url, false);
}
static public string GetDomainFromUrl(Uri Url, bool Strict)
{
initializeTLD();
if (Url == null) return null;
var dotBits = Url.Host.Split('.');
if (dotBits.Length == 1) return Url.Host; //eg http://localhost/blah.php = "localhost"
if (dotBits.Length == 2) return Url.Host; //eg http://blah.co/blah.php = "localhost"
string bestMatch = "";
foreach (var tld in DOMAINS)
{
if (Url.Host.EndsWith(tld, StringComparison.InvariantCultureIgnoreCase))
{
if (tld.Length > bestMatch.Length) bestMatch = tld;
}
}
if (string.IsNullOrEmpty(bestMatch))
return Url.Host; //eg http://domain.com/blah = "domain.com"
//add the domain name onto tld
string[] bestBits = bestMatch.Split('.');
string[] inputBits = Url.Host.Split('.');
int getLastBits = bestBits.Length + 1;
bestMatch = "";
for (int c = inputBits.Length - getLastBits; c < inputBits.Length; c++)
{
if (bestMatch.Length > 0) bestMatch += ".";
bestMatch += inputBits[c];
}
return bestMatch;
}
static private void initializeTLD()
{
if (DOMAINS.Count > 0) return;
string line;
StreamReader reader = File.OpenText("effective_tld_names.dat");
while ((line = reader.ReadLine()) != null)
{
if (!string.IsNullOrEmpty(line) && !line.StartsWith("//"))
{
DOMAINS.Add(line);
}
}
reader.Close();
}
// This file was taken from https://publicsuffix.org/list/effective_tld_names.dat
static public List<String> DOMAINS = new List<String>();
}
}
Я думаю, что вы обнаруживаете непонимание того, что составляет "доменное имя" - в общем использовании нет такого понятия, как "чистое доменное имя" - это то, что вам нужно будет определить, хотите ли вы согласованные результаты. < ш > Вы просто хотите удалить часть "www"? И еще есть другая версия, которая удаляет домен верхнего уровня (например, удаляйте части ".com" или ".co.uk" и т.д.)? В другом ответе упоминается split ( "." ) - вам нужно будет использовать что-то вроде этого, если вы хотите вручную исключить определенные части имени хоста, в рамках .NET Framework ничего не должно точно соответствовать вашим требованиям - вам нужно будет реализовать эти вещи сами.
Смотрите недавно блог Rick Strahl в качестве ссылки для некоторых С# и .net-ориентиров:
Да, ive разместил решение здесь: http://pastebin.com/raw.php?i=raxNQkCF
Если вы хотите удалить расширение, просто добавьте
if (url.indexof(".")>-1) {url = url.substring(0, url.indexof("."))}
Uri Host всегда возвращает домен (www.google.com), включая метку (www) и домен верхнего уровня (com). Но часто вы хотите извлечь средний бит. Просто я делаю
Uri uri;
bool result = Uri.TryCreate(returnUri, UriKind.Absolute, out uri);
if (result == false)
return false;
//if you are sure it not "localhost"
string domainParts = uri.Host.Split('.');
string topLevel = domainParts[domainParts.Length - 1]
string hostBody = domainParts[domainParts.Length - 2]
string label = domainParts[domainParts.Length - 3]
Но вам нужно проверить domainParts.length, так как часто данный uri похож на "google.com".
Использовать Nager.PublicSuffix
установочный пакет Nager.PublicSuffix
var domainParser = new DomainParser(new WebTldRuleProvider());
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";
Я придумал следующее решение (используя Linq):
public string MainDomainFromHost(string host)
{
string[] parts = host.Split('.');
if (parts.Length <= 2)
return host; // host is probably already a main domain
if (parts[parts.Length - 1].All(char.IsNumber))
return host; // host is probably an IPV4 address
if (parts[parts.Length - 1].Length == 2 && parts[parts.Length - 2].Length == 2)
return string.Join(".", parts.TakeLast(3)); // this is the case for co.uk, co.in, etc...
return string.Join(".", parts.TakeLast(2)); // all others, take only the last 2
}
Из-за многочисленных вариаций доменных имен и отсутствия реального авторитетного списка того, что представляет собой "чистое доменное имя", как вы описали, я только что использовал использование Uri.Host в прошлом. Чтобы избежать случаев, когда www.google.com и google.com отображаются в виде двух разных доменов, я часто прибегал к удалению www. из всех доменов, которые его содержат, так как он почти гарантированно (ALMOST) указывает на тот же сайт. Это действительно единственный простой способ сделать это, не рискуя потерять некоторые данные.
string domain = new Uri(HttpContext.Current.Request.Url.AbsoluteUri).GetLeftPart(UriPartial.Authority);