从列表c#中过滤重复的URL域

时间:2011-06-22 13:16:31

标签: c# .net vb.net winforms filter

我有一个列表中的100,000个网址列表(字符串),其中可以包含表单中的网址。

yahoo.com
http://yahoo.com
http://www.yahoo.com

我尝试过使用正则表达式和Uri类的组合,但这没有帮助,所以我抛弃了代码。我也试过使用这个代码,但它只会删除精确形式的重复,因为它不是特定于域的。

list = new ArrayList<T>(new HashSet<T>(list))

如果它们包含相同的名称,例如yahoo,如何过滤这些重复并保留其中一个url。

感谢

[编辑]

请注意

所有网址都属于不同的域名,但通常可以像上面给出的示例一样重复

另外,我正在使用.net 2.0,所以我不能使用linq

4 个答案:

答案 0 :(得分:3)

这对我有用

    [TestMethod]
    public void TestMethod1()
    {
        var sites = new List<string> {"yahoo.com", "http://yahoo.com", "http://www.yahoo.com"};

        var result = sites.Select(
            s =>
            s.StartsWith("http://www.")
                ? s
                : s.StartsWith("http://") 
                      ? "http://www." + s.Substring(7) 
                      : "http://www." + s).Distinct();

        Assert.AreEqual(1, result.Count());
    }

答案 1 :(得分:2)

我认为Uri Class能够在这种情况下提供帮助。我不在VS机器上,我可以测试;但是,将Uri构造函数传递给Url的字符串,并尝试使用Host属性进行比较:

List<string> distinctHosts = new List<string>();

foreach (string url in UrlList)
{
    Uri uri = new Uri(url)

    if (! disctinctHosts.Contains(uri.Host))
    {
        distinctHosts.Add(uri.Host);
    }
}

这感觉有点原始,可能更优雅 - 可能没有foreach;但就像我说的那样,我不是一个可以使用它的开发机器。

我认为这可以处理有效Url的任何变体。构建ArrayList不是一个好主意;在我看来,Regex会要求你保留一些可能变得笨拙的自定义“MatchList”。

正如@Damokles指出的那样,你应该进行某种形式的验证。 Uri类 需要协议:'http://'或'ftp://'。你不想假设'badurl.com'实际上是无效的;但是:

if (!url.StartsWith("http://")) { /* add protocol */ } // then check Host domain as above  

...应该足以简单地检索不同的主机或域名。我推荐任何不需要猜测Url任何部分的索引位置的选项,因为它与特定格式紧密绑定。

答案 2 :(得分:1)

您可以使用Uri类和Linq / extension方法执行此操作。诀窍是在将Url与Uri类一起使用之前规范化Url。另请注意,Uri类需要该方案,因此必须添加它不存在的方案。您可以使用Uri类的其他属性来实现不同的结果。下面的示例返回所有唯一的Urls,并以与www.yahoo.com不同的方式处理yahoo.com。

string[] urls = new[] { 
  "yahoo.com",
  "http://yahoo.com",
  "http://www.yahoo.com" };
var unique = urls.
  Select(url => new System.Uri(
    url.StartsWith("http") ? url : "http://" + url).Host).
  Distinct();

(编辑清理格式并使方案添加部分同时支持“http://”和“https://”)

答案 3 :(得分:0)

尝试使用正则表达式然后.*?(\w+\.\w+)$假设您在tld之后没有任何内容。