在編寫一般的爬蟲程式或者搜尋引擎時,首先就是對隊列中的url進行處理,當我們得到一條URL資訊的時候,我們希望能夠将其處理成合适的部分。
http://www2.scut.edu.cn/scutnxq/s/27/t/3/0f/6b/info3947.htm?p=12&sd=12
對于上面這條URL,我們可以将其分為五個部分:
public static string _HOST = "host"; //主機:www2.scut.edu.cn
public static string _RESOURCE = "resource"; //資源:scutnxq/s/27/t/3/0f/6b/info3947.htm
public static string _PROTOCOL = "protocol"; //協定:http
public static string _URL = "url"; //無
public static string _PARAM = "param"; //參數:p=12&sd=12
對于正規表達式的使用,不是本文的重點,是以直接給出解析的正規表達式:
(?<url>(?<protocol>^[a-z][a-z0-9+\-.]*)://(?<host>[a-z0-9\-._~%]+|\[[a-f0-9:.]+\]|\[v[a-f0-9][a-z0-9\-._~%!$&'()*+,;=:]+\]))(?<resource>[a-z0-9\-._~%!$&'()*+,;=:@/]*/?)(?<param>(\?[a-z0-9\-._~%!$&'()*+,;=:@/?]*)?)$
在.NET中,可以對正規表達式比對的部分進行分組,是以在表達式中加入諸如?<key>的部分,便于通過match對象擷取各部分的值。
public static string[] KEYS = { _HOST, _RESOURCE, _PROTOCOL, _URL, _PARAM };
private Dictionary
url = new Dictionary
();
将上述的字段添加到數組中,便于周遊,接着通過以下簡單的程式将各部分解析出來。
private void match(string src,string pattern)
{
MatchCollection mc = Regex.Matches(src, pattern);
foreach (Match m in mc)
{
if (m.Success)
{
for (int i = 0; i < KEYS.Length; i++)
{
add(KEYS[i], m);
}
}
}
}
其中add方法的實作是:
public void add(string key, Match m)
{
if (!"".Equals(m.Groups[key].Value))
url.Add(key, m.Groups[key].Value);
}
public string get(string key)
{
if (!url.ContainsKey(key))
return "";
return url[key];
}
在該對象的外部,通過get方法和定義靜态字段的名稱,擷取相應的值。
string[] urls = { "http://www2.scut.edu.cn/scutnxq/s/27/t/3/0f/6b/info3947.htm?p=12&sd=12",
"http://www2.scut.edu.cn/scutnxq/s/27/t/3/0f/6b/info3947.htm",
"http://www.scut.edu.cn",
"scutnxq/s/27/t/3/0f/6b/info3947.htm"
};
将各種URL進行測試,保證正規表達式的正确。
有很多正規表達式的線上測試工具,推薦一個較為好用的:http://www.myregexp.com/,需要安裝java環境。