从URL获取域/主​​机名的最快方法是什么?

我需要浏览一个大的字符串url列表并从中提取域名。

例如:

http://www.stackoverflow.com/questions将摘录www.stackoverflow.com

我最初使用的是new URL(theUrlString).getHost()但是URL对象初始化会为进程增加大量时间,而且似乎不需要。

是否有更快的方法来提取可靠的主机名?

谢谢

编辑:我的错误,是的www。 将包含在上面的域名示例中。 此外,这些url可能是http或https

如果你想处理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. Eg 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; } } 

您希望在实施“快速”方式取消URL时要非常小心。 URL中存在许多可能导致“快速”方法失败的可变性。 例如:

  • 方案(协议)部分可以用大写和小写字母的任意组合来编写; 例如“http”,“Http”和“HTTP”是等价的。

  • 权限部分可以可选地包括用户名和/或端口号,如“ http://you@example.com:8080/index.html ”中所示。

  • 由于DNS不区分大小写,因此URL的主机名部分也(有效地)不区分大小写。

  • 对于URL中的方案或权限组件中的非保留字符进行%编码是合法的(尽管非常不规则)。 在匹配(或剥离)方案或解释主机名时,您需要考虑这一点。 具有%编码字符的主机名被定义为等同于解码了%编码序列的主机名。

现在,如果您完全控制生成正在剥离的URL的进程,您可能会忽略这些细节。 但如果它们是从文档或网页中获取的,或者是由人类输入的,那么建议您考虑如果您的代码遇到“不寻常”的URL会发生什么。


如果您关注的是构建URL对象所需的时间,请考虑使用URI对象。 除了其他好处之外,URI对象不会尝试对主机名部分进行DNS查找。

我写了一个方法(见下文),它提取了一个url的域名,并使用简单的String匹配。 它实际上做的是在第一个"://" (或索引0如果没有包含"://" )和第一个后续"/" (或索引String.length()如果没有后续"/" String.length()之间提取位"/" )。 剩下的,前面的"www(_)*." 比特被砍掉了。 我确信会出现这种情况不够好的情况,但在大多数情况下它应该足够好了!

我在这里读到java.net.URI类可以做到这一点(并且优先于java.net.URL类)但我遇到了URI类的问题。 值得注意的是,如果url不包含该方案,即"http(s)"位,则URI.getHost()给出空值。

 /** * 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; } 

你可以写一个正则表达式吗? http://始终相同,然后匹配所有内容,直到获得第一个’/’。

假设它们都是格式正确的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);
int start = theUrlString.indexOf('/'); int start = theUrlString.indexOf('/', start+1); int end = theUrlString.indexOf('/', start+1); String domain = theUrlString.subString(start, end); 

您可以尝试使用正则表达式。

http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html

这是一个关于在Java中使用正则表达式提取域名的问题:

用于检索domain.tld的正则表达式

尝试方法:该类中的getDomainFromUrl()

 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; } } }