正規表示式中的群組是很重要的一個概念,它是我們通往高級正規應用的的橋樑。
組的概念
一個正規表示式匹配結果可以分成多個部分,這就是組(Group)的目的。能夠靈活的使用組後,你會發現Regex真是很方便,而且很強大。
先舉例
public static void Main()
{
string s = "2005-2-21";
Regex reg = new Regex(@"(?<y>d{4})-(?<m>d{1,2})-(?<d>d{1,2})",RegexOptions .Compiled);
Match match = reg.Match(s);
int year = int.Parse(match.Groups["y"].Value);
int month = int.Parse(match.Groups["m"].Value);
int day = int .Parse(match.Groups["d"].Value);
DateTime time = new DateTime(year,month,day);
Console.WriteLine(time);
Console.ReadLine();
}
以上的例子透過群組來實作分析一個字串,並把其轉換成一個DateTime實例,當然,這個函數用DateTime.Parse方法就能很方便的實作。
在這個例子中,我把一次Match結果用(?<name>)的方式分成三個組"y","m","d"分別代表年、月、日。
現在我們已經有了組的概念了,再來看如何分組,很簡單的,除了上在的辦法,我們可以用一對括號就定義出一個組,比如上例可以改成:
public static void Main()
{
string s = "2005-2-21";
Regex reg = new Regex(@"(d{4})-(d{1,2})-(d{1,2})",RegexOptions.Compiled);
Match match = reg.Match(s);
int year = int.Parse(match.Groups[1].Value);
int month = int.Parse(match.Groups[2].Value);
int day = int .Parse(match.Groups[3].Value);
DateTime time = new DateTime(year,month,day);
Console.WriteLine(time);
Console.ReadLine();
}
從上例可以看出,第一個括號對包涵的組別被自動編號為1,後面的括號依序編號為2、3…
public static void Main()
{
string s = "2005-2-21";
Regex reg = new Regex(@"(?<2>d{4})-(?<1>d{1,2})-(?<3>d{1,2})",RegexOptions .Compiled);
Match match = reg.Match(s);
int year = int.Parse(match.Groups[2].Value);
int month = int.Parse(match.Groups[1].Value);
int day = int .Parse(match.Groups[3].Value);
DateTime time = new DateTime(year,month,day);
Console.WriteLine(time);
Console.ReadLine();
}
再看上例,我們用(?<數字>)的方式手工給每個括號對的組編號,(注意我定義1和2的位置時不是從左到右定義的)
通過以上三例,我們知道了為Regex定義Group的三種辦法以及對應的引用組匹配結果的方式。
然後,關於群組定義,還有兩點請注意:
1、因為括號用於定義群組了,所以如果要匹配"("和")",請使用"("和")"(關於所有特殊字元的定義,請查看相關Regex expression幫助文件)。
2、如果定義Regex時,使用了ExplicitCapture選項,則第二個例子不會成功,因為此選項要求明確定義了編號或名字的組才捕獲並保存結果,如果你沒有定義ExplicitCapture選項,而有時又定義了類式於(A|B)這樣的部分在表達式,而這個(A|B)你又不想捕獲結果,那麼可以使用「不捕獲的組」語法,即定義成(?:)的方式,針對於(A|B),你可以這樣來定義以達到不捕獲並保存它到Group集合中的目的-(?:A|B)。