我有一个列表中的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
答案 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之后没有任何内容。