отфильтровать повторяющиеся URL-адреса домена из списка c # - PullRequest
2 голосов
/ 22 июня 2011

У меня есть список из 100 000 URL-адресов в списке (из строки), который может содержать URL-адреса в форме.

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

Я пытался использовать комбинацию регулярных выражений и класса Uri, но это не помогло, поэтому я выбросил код. Я также пытался использовать этот код, но он будет удалять только дубликаты точной формы, поскольку он не зависит от домена.

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

Как отфильтровать эти дубликаты и сохранить только один из этих URL, если он содержит одно и то же имя, например Yahoo.

спасибо

[РЕДАКТИРОВАТЬ]

Обратите внимание, что

все URL относятся к разным доменам, но обычно могут иметь дубликаты, как в примере, который я привел выше

также я использую .net 2.0, поэтому я не могу использовать linq

Ответы [ 4 ]

3 голосов
/ 22 июня 2011

Это сработало для меня

    [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());
    }
2 голосов
/ 22 июня 2011

Я думаю, 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, поскольку он тесно связан с конкретными форматами.

1 голос
/ 22 июня 2011

Вы можете сделать это с помощью класса Uri и методов Linq / extension. Хитрость в том, чтобы нормализовать URL-адрес перед использованием его с классом Uri. Также обратите внимание, что для класса Uri требуется схема, поэтому ее нужно будет добавить для тех, где ее нет. Вы можете использовать другое свойство класса Uri для достижения разных результатов. В приведенном ниже примере возвращаются все уникальные URL-адреса и трактуется yahoo.com иначе, чем www.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://")

0 голосов
/ 22 июня 2011

Попробуйте Regex, затем .*?(\w+\.\w+)$, если у вас ничего нет после tld.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...