Каков самый быстрый способ получить имя домена/хоста из URL?
Мне нужно пройти через большой список строкового url и извлечь из них имя домена.
Например:
http://www.stackoverflow.com/questions извлечет www.stackoverflow.com
Я изначально использовал new URL(theUrlString).getHost()
, но инициализация объекта URL добавляет много времени для процесса и кажется ненужным.
Есть ли более быстрый метод для извлечения имени хоста, которое было бы таким же надежным?
Спасибо
Изменить: Моя ошибка, да, www. будут включены в пример имени домена выше. Кроме того, эти URL могут быть http или https
Ответы
Ответ 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);
Ответ 6
Вы можете попытаться использовать регулярные выражения.
http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html
Вот вопрос об извлечении имени домена с регулярными выражениями в Java:
Регулярное выражение для извлечения domain.tld