域名位於協議後、第一個路徑分隔符(/)或端口號(:)前。標準 URL 結構:
scheme://[user:pass@]host[:port]/path?query#fragment
↑_____________↑
這裡是域名(含子域名)
import java.util.Scanner;
import java.util.regex.*;
public class DomainExtractorV1 {
private static final Pattern DOMAIN_PATTERN = Pattern.compile(
"^(?:https?://)?(?:[^/@:]+@)?([^:/]+)"
);
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("請輸入完整 URL:");
String url = sc.nextLine().trim();
Matcher m = DOMAIN_PATTERN.matcher(url);
if (m.find()) {
System.out.println("提取的域名:" + m.group(1));
} else {
System.out.println("無法解析,請檢查 URL 格式");
}
}
}
測試案例
| 輸入 | 輸出 |
|---|---|
https://www.example.com/path | www.example.com |
https://user:pass@sub.domain.org:8080/api | sub.domain.org |
ftp://files.server.net | files.server.net |
import java.util.*;
public class DomainExtractorV2 {
private static final String[] URL_POOL = {
"https://www.google.com/search?q=java",
"https://github.com/spring-projects/spring-boot",
"https://docs.oracle.com/javase/8/docs/api/",
"https://stackoverflow.com/questions/tagged/java",
"https://www.baidu.com/s?wd=spring"
};
public static void main(String[] args) {
Random rand = new Random();
String url = URL_POOL[rand.nextInt(URL_POOL.length)];
System.out.println("隨機選取 URL:" + url);
// 復用 V1 的正則邏輯
Pattern p = Pattern.compile("^(?:https?://)?(?:[^/@:]+@)?([^:/]+)");
Matcher m = p.matcher(url);
if (m.find()) {
System.out.println("域名:" + m.group(1));
}
}
}
java.net.URI 解析(更健壯)import java.net.URI;
import java.net.URISyntaxException;
public class DomainExtractorURI {
public static String extractHost(String url) {
try {
URI uri = new URI(url);
String host = uri.getHost(); // 自動去除 user:pass、port
return host != null ? host : "解析失敗";
} catch (URISyntaxException e) {
return "非法 URL:" + e.getMessage();
}
}
public static void main(String[] args) {
String[] tests = {
"https://user:pass@api.example.com:8443/v1/resource",
"https://localhost:8080/app",
"invalid-url"
};
for (String u : tests) {
System.out.printf("%-55s → %s%n", u, extractHost(u));
}
}
}
輸出
https://user:pass@api.example.com:8443/v1/resource → api.example.com
https://localhost:8080/app → localhost
invalid-url → 非法 URL:Illegal character in scheme name at index 0
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 手寫正則 | 無依賴、可精確控制提取規則 | 需自行處理邊界情況(IPv6、非標準協議) | 簡單提取、教學演示 |
java.net.URI | 標準庫、自動處理編碼/端口/認證資訊、RFC 3986 合規 | 嚴格模式下異常 URL 會拋棄異常 | 生產環境、需高可靠性 |
第三方庫(Guava InternetDomainName、Apache HttpClient) | 支援公共後綴列表(PSL)、可再提取「根域名」如 example.com | 引入依賴 | 需區分子域名/根域名、安全審計 |
java.net.URI 或 java.net.URL 解析後取 getHost()。InternetDomainName.from(host).topPrivateDomain()。URISyntaxException/MalformedURLException 並記錄日誌,避免拋出干擾主流程。