我试图从URL字符串中提取域名。我几乎拥有它...我正在使用URI
我有一个字符串..我的第一个想法是使用正则表达式,但后来我决定使用URI类
我需要将上面的内容转换为google.com和google而不使用www
我做了以下
Uri test = new Uri(referrer);
log.Info("Domain part : " + test.Host);
基本上这会返回www.google.com ....如果可能的话,我想尝试返回2个表单......如上所述......
google.com 和谷歌
这可以用URI吗?
答案 0 :(得分:28)
是的,可以使用:
Uri.GetLeftPart( UriPartial.Authority )
答案 1 :(得分:17)
@Dewfy:缺陷是你的方法返回“uk”为“www.test.co.uk”,但这里的域名显然是“test.co.uk”。
@naivists:缺陷是您的方法返回“www.beta.microsoft.com”的“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
答案 2 :(得分:6)
google.com不保证与www.google.com相同(嗯,从这个例子来看,它在技术上是,但可能是其他方式)。
也许你需要的是删除“顶级”域名和“www”子域名?然后只需split('.')
并在最后一部分之前取出部分!
答案 3 :(得分:5)
以下是一些仅提供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,则需要稍微调整代码。对于我们来说,这个代码将涵盖几乎每个gTLD和ccTLD,减去一些非常奇特的代码。
答案 4 :(得分:5)
我几乎尝试了所有方法,但所有方法都达不到预期的效果。 所以这是我从servermanfail调整的方法。
https://publicsuffix.org/list/上提供了tld文件 我从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>();
}
}
答案 5 :(得分:3)
我认为您对“域名”的构成存在误解 - 在常见用法中没有“纯域名”这一点 - 如果您想要一致的结果,则需要定义。<登记/> 你只想剥去“www”部分吗? 然后有另一个版本剥离顶级域名(例如剥离“.com”或“.co.uk”等部分?) 另一个答案提到了split(“。”) - 如果你想手动排除主机名的特定部分,你将需要使用这样的东西,.NET框架中没有任何内容可以完全满足你的要求 - 你需要实现这些事情你自己。
答案 6 :(得分:3)
最近看到Rick Strahl的博客作为一些c#和.net中心的参考:
答案 7 :(得分:1)
是的,我已在此处发布了解决方案:http://pastebin.com/raw.php?i=raxNQkCF
如果您想删除扩展名,只需添加
if (url.indexof(".")>-1) {url = url.substring(0, url.indexof("."))}
答案 8 :(得分:1)
Uri的主持人总是返回域名(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's 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”。
答案 9 :(得分:1)
使用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";
答案 10 :(得分:1)
我想出了以下解决方案(使用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
}
答案 11 :(得分:0)
我为自己找到了解决方案,并且没有使用任何TLD或其他东西。
使用以下事实:所谓的主机名始终位于Uri的主机部分中,位于倒数第二个位置。子域始终位于名称的前面,而TLD始终位于名称的后面。
查看此处:
private static string GetNameFromHost(string host)
{
if (host.Count(f => f == '.') == 1)
{
return host.Split('.')[0];
}
else
{
var _list = host.Split('.').ToList();
return _list.ElementAt(_list.Count - 2);
}
}
答案 12 :(得分:-1)
由于域名的众多变化以及您所描述的构成“纯域名”的任何真实权威列表的不存在,我过去只是使用了Uri.Host。为避免www.google.com和google.com显示为两个不同的域名,我经常使用剥离www。来自包含它的所有域,因为它几乎保证(ALMOST)指向同一站点。它实际上是唯一一种简单的方法,可以避免丢失一些数据。
答案 13 :(得分:-1)
string domain = new Uri(HttpContext.Current.Request.Url.AbsoluteUri).GetLeftPart(UriPartial.Authority);