2011-01-28 61 views
17

我需要瀏覽一大串字符串url並從中提取域名。從網址獲取域/主​​機名的最快方式是什麼?

例如:

http://www.stackoverflow.com/questions將提取www.stackoverflow.com

我本來使用new URL(theUrlString).getHost()但URL對象初始化增添了不少時間的過程,似乎不需要。

有沒有更快速的方法來提取主機名稱將是可靠的?

感謝

編輯:我的錯,是萬維網。將包含在上面的域名示例中。此外,這些URL可以是HTTP或HTTPS

+0

你可以使用正則表達式或一些簡單的字符串操作將其解壓,即刪除領導`HTTP://`或`的https ://`然後把所有東西都帶到第一個`/`或`:`(端口 - 不知道你是否想要這個)。然而,我不確定這是否涵蓋所有情況(因此是評論而不是回答) – 2011-01-28 08:09:31

回答

35

如果你想處理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; 
    } 
} 
+0

這幾乎是我使用的新URL()。getHost()方法的12倍,並且它看起來也很有用。我將嘗試獲得一個好的正則表達式模式並運行更多的基準測試,然後將其標記爲已回答,但這是一個很好的改進! – cottonBallPaws 2011-01-28 17:57:19

+0

此外,我不得不稍微更改您的代碼以添加檢查以防尾隨/不存在。 – cottonBallPaws 2011-01-28 17:59:48

+0

啊,是的,好點!隨時編輯我的答案,幷包括您的改進! – aioobe 2011-01-28 18:01:41

0

你可以寫一個正則表達式? http://總是相同的,然後匹配所有內容,直到獲得第一個'/'。

0

假設他們都是很好形成的網址,但你不」知道他們是否會爲http://,https://開頭,等

 

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

你要相當小心,實現「快」​​的方式unpicking網址。網址中存在很多可能導致「快速」方法失敗的可能性。例如:

  • 方案(協議)部分可以寫成大寫和小寫字母的任意組合;例如「http」,「Http」和「HTTP」是等價的。

  • 權威部分可以選擇性地包含用戶名和/或端口號,如「http://[email protected]:8080/index.html」中所述。

  • 由於DNS不區分大小寫,URL的主機名部分也是(有效)不區分大小寫。

  • 這是合法的(雖然非常不規範)% - 編碼URL的方案或權威組件中未預留的字符。在匹配(或剝離)方案或解釋主機名時,您需要考慮這一點。具有%編碼字符的主機名定義爲等同於解碼%編碼序列的主機名。

現在,如果您完全控制生成要剝離的URL的過程,那麼您可能會忽略這些細微差別。但是,如果它們是從文檔或網頁收集的,或者是由人類輸入的,則最好建議考慮如果您的代碼遇到「不尋常」URL時可能發生的情況。


如果您關心的是構建URL對象所需的時間,請考慮使用URI對象。除此之外,URI對象不會嘗試DNS查找主機名部分。

2

我寫了一個方法(見下文),它提取一個url的域名,並使用簡單的字符串匹配。它實際上做的是提取第一個"://"(或索引0,如果沒有包含"://")和第一個後續"/"(或索引String.length(),如果沒有後續"/")之間的位。其餘的,前面的"www(_)*."位被切斷。我相信會有這樣的情況發生,但這在很多情況下應該足夠好!

我讀herejava.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; 
} 
0

嘗試使用方法: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; 
     } 

    } 
} 
相關問題