正聲明:(?=EXP),括號中的模式必須出現在聲明右側,但不作為匹配的一部分
負聲明:(?!EXP),括號中的模式必須不出現在聲明右側
var x = "1024used2048free"; var r1 = new Regex(@"\d{4}(?=used)"); if (r1.Matches(x).Count==1) { Console.WriteLine("r1 match:" + r1.Match(x).Value); //輸出:1024 } var r2 = new Regex(@"\d{4}(?!used)"); if (r2.Matches(x).Count==1) { Console.WriteLine("r2 match:" + r2.Match(x).Value); //輸出:2048 }
反向正聲明:(?<=EXP),括號中的模式必須出現在聲明左側,但不作為匹配的一部分
反向負聲明:(?<!EXP),括號中的模式必須不出現在聲明左側
string x = "used:1024 free:2048"; Regex r1 = new Regex(@"(?<=used:)\d{4}"); if (r1.Matches(x).Count==1) { Console.WriteLine("r1 match:" + r1.Match(x).Value);
//輸出:1024 }
Regex r2 = new Regex(@"(?<!used:)\d{4}"); if (r2.Matches(x).Count==1) { Console.WriteLine("r2 match:" + r2.Match(x).Value);
//輸出:2048 }
非回溯匹配:(?)
涵義:該組匹配后,其匹配的字符不能通過回溯用於后面的表達式的匹配。呵呵,光看這句話肯定搞不懂,我當初為了搞懂這個也花了不少的時間,還是通過實例來說明吧:
"www.csdn.net" 可以通過@"\w+\.(.*)\.\w+"來匹配,卻不能通過@"\w+\.(?>.*)\.\w+"來匹配!為什么呢?
原因是正則匹配是貪婪的,匹配時它會盡可能多的匹配最多的結果,所以,上例兩個正則式中的.*都會把csdn.net匹配完, 這個時候,第一個表達式在開始匹配時發現\.\w+沒得字符給它匹配了,所以它會進行回溯,所謂回溯,就是把.*匹配的結果往回推,回推留出來的字符再用來匹配\.\w+,直到\.\w+匹配成功,整個表達式返回成功的匹配結果。而第二個表達式,因使用的是非回溯匹配,所以,.*匹配完后,不允許通過回溯來匹配\.\w+,所以整個表達式匹配失敗。
請注意,回溯匹配是很浪費資源的一種匹配方式,所以,請盡量避免您的正則式要通過回溯來成功匹配,如上例,可以換成@"\w+\.([^\.]+\.)+\w+"+"。