C# 从 Url 中提取通配符域

C# Extract wildcard domain from Url

我想从URL中提取域名。其中还将包括通配符。除了通配符之外,它应该是一个有效的域。

可接受的域

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

不可接受的域

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# System.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