如何比较带www与不带www的两个URL?能否用Uri.Compare实现?
问题解答
能否用Uri.Compare实现此类URL比较?
不能。Uri.Compare方法中的UriComponents.Host和UriComponents.NormalizedHost都是基于完整域名进行比较的,www.example.com和example.com会被视为两个不同的主机地址,所以无法通过该方法直接判定二者相似。
替代方案
方案1:移除常见前缀后比较(适合简单场景)
如果业务只需要忽略www.这类常见前缀,可以编写辅助方法先处理Uri的Host部分,再结合路径和查询参数进行比较:
Uri uri1 = new Uri("http://www.example.com"); Uri uri2 = new Uri("http://example.com"); // 处理Host,移除开头的www. string GetNormalizedHost(Uri uri) { var host = uri.Host; return host.StartsWith("www.", StringComparison.OrdinalIgnoreCase) ? host.Substring(4) : host; } // 比较处理后的Host,以及路径和查询参数 bool areSimilar = string.Equals(GetNormalizedHost(uri1), GetNormalizedHost(uri2), StringComparison.OrdinalIgnoreCase) && Uri.Compare(uri1, uri2, UriComponents.PathAndQuery, UriFormat.SafeUnescaped, StringComparison.OrdinalIgnoreCase) == 0; Console.WriteLine(areSimilar); // 输出 True
方案2:解析主域名进行比较(适合复杂多子域名场景)
如果需要处理更复杂的子域名(比如blog.example.co.uk、shop.example.com这类),可以借助公共后缀列表来提取域名的注册主体部分(即主域名),再进行比较。可以通过NuGet安装PublicSuffix库,实现逻辑如下:
using PublicSuffix; Uri uri1 = new Uri("http://www.example.com"); Uri uri2 = new Uri("http://example.com"); // 获取主域名 string GetRegisteredDomain(Uri uri) { var parser = new DomainParser(new WebTldRuleProvider()); var domainInfo = parser.Parse(uri.Host); return domainInfo.RegisteredDomain; } bool areSimilar = string.Equals(GetRegisteredDomain(uri1), GetRegisteredDomain(uri2), StringComparison.OrdinalIgnoreCase) && Uri.Compare(uri1, uri2, UriComponents.PathAndQuery, UriFormat.SafeUnescaped, StringComparison.OrdinalIgnoreCase) == 0; Console.WriteLine(areSimilar); // 输出 True
方案3:自定义相似规则(灵活适配业务需求)
如果业务有特定的前缀/子域名规则(比如允许m.、mobile.也视为同一域名),可以扩展方案1的逻辑,维护一个需要忽略的前缀列表,批量处理Host后再比较:
Uri uri1 = new Uri("http://m.example.com"); Uri uri2 = new Uri("http://example.com"); var ignoredPrefixes = new HashSet<string> { "www.", "m.", "mobile." }; string GetNormalizedHost(Uri uri) { var host = uri.Host.ToLowerInvariant(); foreach (var prefix in ignoredPrefixes) { if (host.StartsWith(prefix)) { return host.Substring(prefix.Length); } } return host; } bool areSimilar = string.Equals(GetNormalizedHost(uri1), GetNormalizedHost(uri2), StringComparison.OrdinalIgnoreCase) && Uri.Compare(uri1, uri2, UriComponents.PathAndQuery, UriFormat.SafeUnescaped, StringComparison.OrdinalIgnoreCase) == 0; Console.WriteLine(areSimilar); // 输出 True
内容的提问来源于stack exchange,提问作者Stephen Murumba
相关产品推荐
相关产品推荐

