前言:最近使用到了他人總結的一個基礎類庫。查看了下源碼,發現String幫助類的一個輔助方法不是很嚴謹,重構之。
1、原來程序的寫法
public static string GetDomainName(string url)
{
Regex reg = new Regex(@"http(s)?://([\w-]+\.)+[\w-]+/?");
string result = reg.Match(url, 0).Value;
if (result.IndexOf("http://") > -1)
{
result = result.Replace("http://", string.Empty);
}
else if (result.IndexOf("https://") > -1)
{
result = result.Replace("https://", string.Empty);
}
return result.Replace("/", string.Empty);
}
2、改進方案
上面的寫法,我認爲不嚴謹的地方有兩處:a、沒有區分部分字符串的大小寫(雖然通常傳入的url都是小寫http(s)開頭的,使用起來問題不大);b、參數沒有考慮爲null的情況。下面給出我的幾種解決方法,個人認爲相對而言比較簡潔嚴謹一些。
(1)正則改進
按照原來代碼的寫法,正則表達式是先提取出形如 http://www.cnblogs.com/ 的形式的字符串,然後再處理字符串。字符串替換和hard coding看起來會比較多,而且,毫無疑問,上面代碼中的正則提取的字符串稍顯冗餘。我的改進如下:
public static string GetDomainName(string url)
{
if (url == null)
{
throw new Exception("輸入的url爲空");
}
Regex reg = new Regex(@"(?<=[://])([\w-]+\.)+[\w-]+/?", RegexOptions.IgnoreCase);
return reg.Match(url, 0).Value.Replace("/", string.Empty);
}
應該說這是比較忠實於源代碼的一種實現。
【UPDATE】:根據文章後面布袋和尚說不得大師的指點,再改進一下正則表達式,這樣對於正常的url路徑或其他類型的路徑都可以進行驗證匹配了。代碼如下:
public static string GetDomainName(string url)
{
if (url == null)
{
throw new Exception("輸入的url爲空");
}
Regex reg = new Regex(@"(?<=://)([\w-]+\.)+[\w-]+(?<=/?)");
return reg.Match(url, 0).Value.Replace("/", string.Empty);
}
(2)直接拼接字符串
拼接字符串在實際開發中可以做很多事情,簡單的域名提取自然不在話下。我們分析一下輸入的url,發現很顯著也很重要的一個特徵就是通過斜線(/)來分割字符串,每一個分隔後的字符串分別表示不同的屬性,如對應的協議名稱,域名,站點名,頁面名稱等等。具體分割拼接提取的方法如下:
public static string GetDomainName(string url)
{
if (url == null)
{
throw new Exception("輸入的url爲空");
}
string result = string.Empty;
string[] strArr = url.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string item in strArr)
{
if (string.Compare("http:", item.ToLower()) == 0)
{
continue;
}
else if (string.Compare("https:", item.ToLower()) == 0)
{
continue;
}
result = item;
break;
}
return result;
}
嚴格來說,這個是比較“笨”的方法,但是通俗易懂。
(3)通過一個HttpRequest對象獲取它的Url的Host
平時我們都是通過HttpRequest對象獲取它的Url的Host來獲取網站域名,現在只有一個字符串參數url,很顯然,我們會想到構造一個HttpRequest對象,然後按步就班即可。具體方法如下:
public static string GetDomainName(string url)
{
string result = null;
try
{
HttpRequest request = new HttpRequest(string.Empty, url, string.Empty);
result = request.Url.Host;
}
catch (Exception ex)
{
throw new Exception(string.Format("當前輸入的URL:{0},發生異常:{1}", url, ex.Message));
}
return result;
}
這個應該算是另闢蹊徑的一種解決方案,可是必需要引用System.Web dll,作爲基礎類庫,應該越少引用越好。
結語:到這裏,根據url提取host的常規方法基本重構完成,沒有過分考慮效率和性能,不知哪種會更快一點。期待您更好的方法和意見。