Je dois parcourir une longue liste d'URL de chaînes et en extraire le nom de domaine.
Par exemple:
http://www.stackoverflow.com/questions extrairait www.stackoverflow.com
À l'origine, j'utilisais new URL(theUrlString).getHost()
, mais l'initialisation de l'objet URL ajoute beaucoup de temps au processus et semble inutile.
Existe-t-il une méthode plus rapide pour extraire le nom d'hôte qui serait aussi fiable?
Merci
Edit: Mon erreur, oui le www. serait inclus dans l'exemple de nom de domaine ci-dessus. En outre, ces URL peuvent être http ou https.
Si vous voulez gérer https
etc., je vous suggère de faire quelque chose comme ceci:
int slashslash = url.indexOf("//") + 2;
domain = url.substring(slashslash, url.indexOf('/', slashslash));
Notez que cela inclut la partie www
(comme le ferait URL.getHost()
) qui fait en réalité partie du nom de domaine.
Edit demandé via des commentaires
Voici deux méthodes qui pourraient être utiles:
/**
* 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;
}
}
Vous voulez être assez prudent avec la mise en œuvre d'une manière "rapide" de désélectionner les URL. Il existe une grande variabilité potentielle dans les URL qui pourrait entraîner l'échec d'une méthode "rapide". Par exemple:
La partie schéma (protocole) peut être écrite avec n’importe quelle combinaison de lettres majuscules et minuscules; par exemple. "http", "Http" et "HTTP" sont équivalents.
La partie autorité peut éventuellement inclure un nom d'utilisateur et/ou un numéro de port, comme suit: " http: //[email protected]: 8080/index.html ".
Étant donné que DNS est insensible à la casse, la partie nom d'hôte d'une URL est également (effectivement) insensible à la casse.
Il est légal (bien que très irrégulier) de% coder des caractères non réservés dans les composants de schéma ou d'autorité d'une URL. Vous devez en tenir compte lors de la mise en correspondance (ou de la suppression) du schéma, ou lors de l'interprétation du nom d'hôte. Un nom d’hôte avec des caractères%-codés est défini pour être équivalent à un avec les séquences%-codées décodées.
Maintenant, si vous avez un contrôle total sur le processus qui génère les URL que vous supprimez, vous pouvez probablement ignorer ces subtilités. Mais si elles sont extraites de documents ou de pages Web, ou entrées par des humains, vous feriez bien de réfléchir à ce qui pourrait se passer si votre code rencontre une URL "inhabituelle".
Si votre préoccupation concerne le temps nécessaire à la construction des objets URL, envisagez plutôt d'utiliser des objets URI. Parmi les bonnes choses, les objets URI ne tentent pas une recherche DNS de la partie nom d’hôte.
J'ai écrit une méthode (voir ci-dessous) qui extrait le nom de domaine d'une URL et qui utilise une correspondance simple. En fait, il extrait le bit entre le premier "://"
(ou l'index 0
s'il n'y a pas de "://"
contenu) et le premier "/"
suivant (ou l'index String.length()
s'il n'y a pas de "/"
suivant). Le dernier bit "www(_)*."
restant est coupé. Je suis sûr qu'il y aura des cas où ce ne sera pas assez bon mais ça devrait l'être assez dans la plupart des cas!
J'ai lu ici que la classe Java.net.URI
pouvait le faire (et était préférée à la classe Java.net.URL
) mais j'ai rencontré des problèmes avec la classe URI
. Notamment, URI.getHost()
donne une valeur nulle si l’URL n’inclut pas le schéma, c’est-à-dire le bit "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;
}
Vous pourriez écrire une expression rationnelle? http: // est toujours le même, puis correspond à tout jusqu'à ce que vous obteniez le premier '/'.
En supposant que ce sont toutes des URL bien formées, mais vous ne savez pas si elles seront http: //, https: //, etc.
int start = theUrlString.indexOf('/');
int start = theUrlString.indexOf('/', start+1);
int end = theUrlString.indexOf('/', start+1);
String domain = theUrlString.subString(start, end);
Vous pouvez essayer d'utiliser des expressions régulières.
http://download.Oracle.com/javase/6/docs/api/Java/util/regex/Pattern.html
Voici une question sur l'extraction de nom de domaine avec des expressions régulières en Java:
Essayez la méthode: getDomainFromUrl () dans cette classe
package com.visc.mobilesecurity.childrencare.utils;
import Android.content.Context;
import com.visc.mobilesecurity.antitheft.backwardcompatibility.FroyoSupport;
import com.visc.mobilesecurity.antitheft.util.AntiTheftUtils;
import com.visc.mobilesecurity.constant.Key;
import com.visc.mobilesecurity.util.Prefs;
import org.json.JSONObject;
import Java.io.File;
import Java.io.FileOutputStream;
import Java.io.InputStream;
/**
* Created by thongnv12 on 3/9/2018.
*/
public class ChildcareUtils {
public static final String[] NATION_DOMAIN = {"af", "ax", "al", "dz", "as", "ad", "ao", "ai", "aq", "ag", "ar", "am", "aw", "ac", "au", "at", "az", "bs", "bh", "bd", "bb", "eus",
"by", "be", "bz", "bj", "bm", "bt", "bo", "bq", "ba", "bw", "bv", "br", "io", "vg", "bn", "bg", "bf", "mm", "bi", "kh", "cm", "ca", "cv", "cat", "ky", "cf", "td", "cl",
"cn", "cx", "cc", "co", "km", "cd", "cg", "ck", "cr", "ci", "hr", "cu", "cw", "cy", "cz", "dk", "dj", "dm", "do", "tl", "ec", "eg", "sv", "gq", "er", "ee", "et", "eu",
"fk", "fo", "fm", "fj", "fi", "fr", "gf", "pf", "tf", "ga", "gal", "gm", "ps", "ge", "de", "gh", "gi", "gr", "gl", "Gd", "gp", "gu", "gt", "gg", "gn", "gw", "gy", "ht",
"hm", "hn", "hk", "hu", "is", "in", "id", "ir", "iq", "ie", "im", "il", "it", "jm", "jp", "je", "jo", "kz", "ke", "ki", "kw", "kg", "la", "lv", "lb", "ls", "lr", "ly",
"li", "lt", "lu", "mo", "mk", "mg", "mw", "my", "mv", "ml", "mt", "mh", "mq", "mr", "mu", "yt", "mx", "md", "mc", "mn", "me", "ms", "ma", "mz", "mm", "na", "nr", "np",
"nl", "nc", "nz", "ni", "ne", "ng", "nu", "nf", "kp", "mp", "no", "om", "pk", "pw", "ps", "pa", "pg", "py", "pe", "ph", "pn", "pl", "pt", "pr", "qa", "ro", "ru", "rw",
"re", "bq", "bl", "sh", "kn", "lc", "mf", "fr", "pm", "vc", "ws", "sm", "st", "sa", "sn", "rs", "sc", "sl", "sg", "bq", "sx", "sk", "si", "sb", "so", "so", "za", "gs",
"kr", "ss", "es", "lk", "sd", "sr", "sj", "sz", "se", "ch", "sy", "tw", "tj", "tz", "th", "tg", "tk", "to", "tt", "tn", "tr", "tm", "tc", "tv", "ug", "ua", "ae", "uk",
"us", "vi", "uy", "uz", "vu", "va", "ve", "vn", "wf", "eh", "zm", "zw"};
public static boolean isInNationString(String str) {
for (int index = 0; index < NATION_DOMAIN.length; index++) {
if (NATION_DOMAIN[index].equals(str)) {
return true;
}
}
return false;
}
public static String getDomainFromUrl(String urlStr) {
try {
String result = null;
// URL url = new URL(urlStr);
// result = url.getHost();
// return result;
//
// for test
// check dau cach
if (urlStr.contains(" ")) {
return null;
}
// replace
urlStr = urlStr.replace("https://", "");
urlStr = urlStr.replace("http://", "");
urlStr = urlStr.replace("www.", "");
//
String[] splitStr = urlStr.split("/");
String domainFull = splitStr[0];
String[] splitDot = domainFull.split("\\.");
if (splitDot.length < 2) {
return null;
}
String nationStr = splitDot[splitDot.length - 1];
if (isInNationString(nationStr)) {
if (splitDot.length < 4) {
result = domainFull;
} else {
StringBuilder strResult = new StringBuilder();
int lengthDot = splitDot.length;
strResult.append(splitDot[lengthDot - 3]).append(".");
strResult.append(splitDot[lengthDot - 2]).append(".");
strResult.append(splitDot[lengthDot - 1]);
result = strResult.toString();
}
} else {
if (splitDot.length < 3) {
result = domainFull;
} else {
StringBuilder strResult = new StringBuilder();
int lengthDot = splitDot.length;
strResult.append(splitDot[lengthDot - 2]).append(".");
strResult.append(splitDot[lengthDot - 1]);
result = strResult.toString();
}
}
return result;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
}