Подтвердить что ты не робот

Каков самый быстрый способ получить имя домена/хоста из URL?

Мне нужно пройти через большой список строкового url и извлечь из них имя домена.

Например:

http://www.stackoverflow.com/questions извлечет www.stackoverflow.com

Я изначально использовал new URL(theUrlString).getHost(), но инициализация объекта URL добавляет много времени для процесса и кажется ненужным.

Есть ли более быстрый метод для извлечения имени хоста, которое было бы таким же надежным?

Спасибо

Изменить: Моя ошибка, да, www. будут включены в пример имени домена выше. Кроме того, эти URL могут быть http или https

4b9b3361

Ответ 1

Если вы хотите обрабатывать https и т.д., я предлагаю вам сделать что-то вроде этого:

int slashslash = url.indexOf("//") + 2;
domain = url.substring(slashslash, url.indexOf('/', slashslash));

Обратите внимание, что это включает в себя часть www (как это делал URL.getHost()), которая фактически является частью имени домена.

Изменить запрос через комментарии

Вот два метода, которые могут быть полезны:

/**
 * Will take a url such as http://www.stackoverflow.com and return www.stackoverflow.com
 * 
 * @param url
 * @return
 */
public static String getHost(String url){
    if(url == null || url.length() == 0)
        return "";

    int doubleslash = url.indexOf("//");
    if(doubleslash == -1)
        doubleslash = 0;
    else
        doubleslash += 2;

    int end = url.indexOf('/', doubleslash);
    end = end >= 0 ? end : url.length();

    int port = url.indexOf(':', doubleslash);
    end = (port > 0 && port < end) ? port : end;

    return url.substring(doubleslash, end);
}


/**  Based on : http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.3_r1/android/webkit/CookieManager.java#CookieManager.getBaseDomain%28java.lang.String%29
 * Get the base domain for a given host or url. E.g. mail.google.com will return google.com
 * @param host 
 * @return 
 */
public static String getBaseDomain(String url) {
    String host = getHost(url);

    int startIndex = 0;
    int nextIndex = host.indexOf('.');
    int lastIndex = host.lastIndexOf('.');
    while (nextIndex < lastIndex) {
        startIndex = nextIndex + 1;
        nextIndex = host.indexOf('.', startIndex);
    }
    if (startIndex > 0) {
        return host.substring(startIndex);
    } else {
        return host;
    }
}

Ответ 2

Вы хотите проявлять осторожность при внедрении "быстрого" способа удаления URL-адресов. В URL-адресах существует много потенциальной изменчивости, которая может привести к сбою "быстрого" метода. Например:

  • Часть схемы (протокола) может быть записана в любой комбинации букв верхнего и нижнего регистра; например "http", "Http" и "HTTP" эквивалентны.

  • Часть полномочий может необязательно включать имя пользователя и/или номер порта, как в " http://[email protected]:8080/index.html".

  • Поскольку DNS нечувствителен к регистру, часть имени хоста URL-адреса также (эффективно) нечувствительна к регистру.

  • Это законно (хотя и очень нерегулярно) к% -encode незаслуженным символам в схеме или компонентах полномочий URL-адреса. Это необходимо учитывать при сопоставлении (или снятии) схемы или при интерпретации имени хоста. Имя хоста с символами% -encoded определено как эквивалентное одному с декодированными последовательностями% -encoded.

Теперь, если у вас есть полный контроль над процессом, который генерирует URL-адреса, которые вы удаляете, вы, вероятно, можете игнорировать эти тонкости. Но если их собирают из документов или веб-страниц или вводят люди, вам будет полезно подумать о том, что может произойти, если ваш код встречает "необычный" URL-адрес.


Если ваша задача - время, затраченное на создание объектов URL, подумайте об использовании объектов URI. Среди других хороших вещей объекты URI не пытаются найти DNS-узел части хоста.

Ответ 3

Я написал метод (см. ниже), который извлекает имя домена url и которое использует простое сопоставление строк. Фактически это извлекает бит между первым "://" (или индексом 0, если там нет "://"), и первым последующим "/" (или индексом String.length(), если нет последующих "/"). Оставшийся, предшествующий бит "www(_)*." прерывается. Я уверен, что будут случаи, когда это будет недостаточно, но в большинстве случаев это должно быть достаточно хорошо!

Я прочитал здесь, что класс java.net.URI мог бы сделать это (и был предпочтительнее класса java.net.URL), но я столкнулся с проблемами с классом URI, Примечательно, что URI.getHost() дает нулевое значение, если url не включает схему, то есть бит "http(s)".

/**
 * Extracts the domain name from {@code url}
 * by means of String manipulation
 * rather than using the {@link URI} or {@link URL} class.
 *
 * @param url is non-null.
 * @return the domain name within {@code url}.
 */
public String getUrlDomainName(String url) {
  String domainName = new String(url);

  int index = domainName.indexOf("://");

  if (index != -1) {
    // keep everything after the "://"
    domainName = domainName.substring(index + 3);
  }

  index = domainName.indexOf('/');

  if (index != -1) {
    // keep everything before the '/'
    domainName = domainName.substring(0, index);
  }

  // check for and remove a preceding 'www'
  // followed by any sequence of characters (non-greedy)
  // followed by a '.'
  // from the beginning of the string
  domainName = domainName.replaceFirst("^www.*?\\.", "");

  return domainName;
}

Ответ 4

Вы можете написать регулярное выражение? http://всегда одно и то же, а затем все совпадают до тех пор, пока вы не получите первый '/'.

Ответ 5

Предполагая, что у них все хорошо сформированные URL-адреса, но вы не знаете, будут ли они http://, https://и т.д.


int start = theUrlString.indexOf('/');
int start = theUrlString.indexOf('/', start+1);
int end = theUrlString.indexOf('/', start+1);
String domain = theUrlString.subString(start, end);