首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# URL 解析利器:一行代碼提取域名、目錄、文件名(含 Regex 與 Uri 兩種方案)

     編輯:關於C語言

前言:別再手寫字串切割了

從 URL 中提取域名、路徑層級、文件名是常見需求。手寫 IndexOf/Substring 易出錯、難維護。.NET 內建 System.Uri 與 Regex 提供健壯、標準化的解析能力,本文提供開箱即用的三個擴充方法。

方案一:System.Uri(推薦,標準、效能佳、自動處理編碼)

public static class UrlExtensions {
    /// 取得域名(含連接埠,不含 scheme)
    public static string GetDomain(this string url) {
        if (Uri.TryCreate(url, UriKind.Absolute, out var uri))
            return uri.Host; // 自動排除 scheme、path、query
        return string.Empty;
    }

    /// 取得路徑目錄層級陣列(不含檔名)
    public static string[] GetDirectories(this string url) {
        if (!Uri.TryCreate(url, UriKind.Absolute, out var uri))
            return Array.Empty();
        
        // AbsolutePath 以 '/' 開頭,TrimStart 移除首個 '/'
        var segments = uri.AbsolutePath.TrimStart('/').Split('/');
        // 最後一段若含 '.' 視為檔名,排除
        if (segments.Length > 0 && segments[^1].Contains('.'))
            return segments[..^1];
        return segments;
    }

    /// 取得檔名(含副檔名)
    public static string GetFileName(this string url) {
        if (!Uri.TryCreate(url, UriKind.Absolute, out var uri))
            return string.Empty;
        
        var segments = uri.AbsolutePath.TrimStart('/').Split('/');
        return segments.Length > 0 && segments[^1].Contains('.') ? segments[^1] : string.Empty;
    }
}

方案二:Regex 進階解析(適用非標準 URL、需自訂群組捕獲)

public static class UrlRegexParser {
    // 命名群組:scheme、host、port、path、file
    private static readonly Regex UrlRegex = new(
        @"^(?https?)://(?[^:/]+)(?::(?\d+))?(?/[^?#]*)?(?:\?(?[^#]*))?(?:#(?.*))?$",
        RegexOptions.Compiled | RegexOptions.IgnoreCase);

    public static string GetDomain(string url) {
        var m = UrlRegex.Match(url);
        return m.Success ? m.Groups["host"].Value : string.Empty;
    }

    public static string[] GetDirectories(string url) {
        var m = UrlRegex.Match(url);
        if (!m.Success) return Array.Empty();
        var path = m.Groups["path"].Value.TrimStart('/');
        if (string.IsNullOrEmpty(path)) return Array.Empty();
        var segs = path.Split('/');
        return segs[^1].Contains('.') ? segs[..^1] : segs;
    }

    public static string GetFileName(string url) {
        var m = UrlRegex.Match(url);
        if (!m.Success) return string.Empty;
        var path = m.Groups["path"].Value.TrimStart('/');
        if (string.IsNullOrEmpty(path)) return string.Empty;
        var segs = path.Split('/');
        return segs[^1].Contains('.') ? segs[^1] : string.Empty;
    }
}

實戰測試

var url = "https://api.example.com:8080/v2/users/profile/avatar.png?token=abc#section";

Console.WriteLine($"域名: {url.GetDomain()}");           // api.example.com
Console.WriteLine($"目錄: {string.Join("/", url.GetDirectories())}"); // v2/users/profile
Console.WriteLine($"檔名: {url.GetFileName()}");           // avatar.png

進階場景:處理相對路徑、查詢字串、片段識別碼

輸入GetDomainGetDirectoriesGetFileName
/static/css/main.css(空)static/cssmain.css
https://site.com/dir/site.comdir(空)
https://site.com/file?name=valsite.com(空)file
https://site.com/path/file.tar.gzsite.compathfile.tar.gz

避坑指南

  1. Uri.TryCreate 必須傳 UriKind.Absolute,否則相對路徑會解析失敗。
  2. AbsolutePath 會自動 URL 解碼(%20 → 空格),若需原始編碼請用 uri.OriginalString 配合 Regex。
  3. 檔名判斷邏輯:單純用「含點」判斷可能誤判(如 api/v1.0/users),實務建議結合 Content-Disposition 標頭或已知副檔名清單。
  4. 效能:Uri 內部快取,高頻呼叫無額外開銷;Regex 建議 Compiled 選項並靜態快取。

總結

優先使用 System.Uri 擴充方法,標準、簡潔、效能佳;僅在非標準 URL 或需複雜群組捕獲時改用 Regex。將上述代碼納入共用類庫,徹底告別手寫字串切割的痛苦。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved