我想从URL中提取域名。其中还包括通配符。除了通配符之外,它应该是一个有效的域。
<<p>可接受域/strong>https://*.google.com => *.google.com
http://*.google.com => *.google.com
*google.com => *google.com
google.com => google.com
any-google.com => any-google.com
www.google.com => www.google.com
https://google.com/something => google.com
google.com/something => google.com
google.com/something?a=23&b=3 => google.com
http://google.com/something?a=23&b=3 => google.com
google.com/something?a=23&b=3#some => google.com
https://google.com/something?a=23&b=3#some => google.com
Non-Acceptable域
http://**.google.com
*.*.google.com
google.*com
goo**le.com
google.*com
google.com*
google--.com
google..com
google-s.com
goolge/$#$
<all invalid URL>
注意:在上面的例子中,只给出了google域名的例子。但它可以是任何定义域
我试过使用c#系统。Uri当有通配符(*)时失败。甚至基于RegExp的解决方案似乎也会给出更多的假阳性或假阴性结果。
private static string ExtractDomainFromUrl(string url)
{
if (Uri.IsWellFormedUriString(url, UriKind.Absolute))
{
return new Uri(url, UriKind.Absolute).Host;
}
return null;
}
当输入URL不是以HTTP或HTTPS开头时,上述解决方案失败。此外,当输入包含通配符(即*.google.com)时,它会失败。
这里有很多问题需要回答。首先,如何区分URL和域名?
var uriRel = new Uri(url, UriKind.RelativeOrAbsolute);
if(!uriRel.IsAbsoluteUri) url = "http://" + url;
我不确定将相对URI视为只是缺少方案是否是一个好的实践,这取决于您如何获得这样的URI,但我认为这在您的情况下是好的。您可能还需要处理以//
开头的";"大小写和其他情况下,它被解析为相对的,但看起来不像一个域。
接下来,如何允许*
字符?你不能,但你肯定可以取代它!
string replacement;
for(int i = 0; ; i++)
{
replacement = "w" + i;
if(!url.Contains(replacement))
{
break;
}
}
var uriObj = new Uri(url.Replace("*", replacement), UriKind.Absolute);
var host = uriObj.IdnHost.Replace(replacement, "*");
这只是试图找到输入中不包含的第一个uri有效字符串,并在替换*
时使用它。
最后一个问题是,如果您成功获得了通配符域,如何验证它。你没有说明实际的规则是什么,所以我想你打算自己实现它。
在任何情况下,都不要忘记捕获UriFormatException。