Regex可以被看成是一個強大的萬用字元(通用匹配符號)。大多數人都應該很熟悉萬用字元,例如,當我們看到一個諸如“SAMS”的運算式,那麼一個文本串中任何以SAMS開頭的字串都可以與這個運算式匹配。Regex提供了比這種萬用字元能力更強、控制規則更複雜、功能更完善的匹配機制。
本文將對.NET架構提供的支援Regex的類做一個概要介紹。要想獲得有關Regex的更多知識,可參考《Regular Expression Pocket Reference 》(O'Reilly Media出版社,ISBN:059600415X)或《Mastering Regular Expressions》,2nd Edition (O'Reilly Media出版社,ISBN:0596002890)等書籍。它們可以教會你如何建立Regex,並提供了最常用的Regex列表。
輸入確認
Regex最重要的用途之一,是確認某個輸入的文本是否符合一個預定義的格式。例如,一個能夠作為密碼的字串通常要遵循某些強制的規則,以使得密碼字串難以被破解。這些規則常常被定義為Regex。Regex也常常用來對一些簡單的輸入執行確認,如確認email地址和電話號碼。
RegEx類是.NET架構中一個處理Regex的關鍵類。RegEx類包含了一個名為IsMatch的靜態方法,它返回一個布爾值,這個布爾值說明指定的輸入串是否與一個給定的Regex匹配。
下面的代碼中,用到了一個常用的Regex,用來測試一個email地址是否有效:
string emailPattern =
@"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)||[ccc]
(([\w-]+\.)+))([a-zA-Z]{2,4}||[0-9]{1,3})(\]?)$";
Console.Write("Enter an e-mail address:");
string emailInput = Console.ReadLine();
bool match = Regex.IsMatch(emailInput, emailPattern);
if (match)
Console.WriteLine("E-mail address is valid.");
else
Console.WriteLine("Supplied input is not a valid e-mail address.");
不要擔心上面的Regex是否有意義。電子郵件模式背後隱藏的基本思想是,它必須包含一些字元,然後是一個@標記,接著是跟在“.”之後的一些字元組合,“.”之後至少要有兩個字元。你可以試著在上面的程式段中使用不同的文本作為輸入,並觀察程式執行的結果。即使你不理解Regex本身的含義,也沒有關係。只要知道存在Regex這樣一種工具,並且它可以用來對輸入進行確認,這對於你編寫應用程式將是極有協助的。
從輸入中抽取資料
Regex另一個常見用途是用來分析文本,並從使用者的輸入中抽取資料(稱為組匹配)。
C#中的Regex包含了一個稱為組(group)的獨特特徵。使用組,可以為Regex中特定的段賦予一個標識符名稱。當調用match() 方法對模式和輸入資料進行比較時,比較的結果實際上是按照組拆分被匹配的符號串,這樣就允許你從輸入中抽取與每個組相匹配的部分。
例如,我們可以在前一個例子中建立一個名為username的組,用它從一個email地址中提取所有位於@之前的符號串。這樣,在執行匹配時,就可以應用Regex中的命名組來抽取使用者名稱資訊。
看看下面的程式碼範例,它說明如何從使用者在控制台輸出的URL地址中同時抽取協議名和連接埠號碼。Regex的一個良好特性是它自身構成了一個語言,這個語言與C、C++、C#或任何其他程式設計語言沒有依賴關係。這使得我們可以容易地從互連網或參考文獻的應用案例中借用某些常用的Regex。例如,下面常式中的Regex借用自MSDN中的一個例子:
string urlPattern = @"^(?<proto>\w+)://[^/]+?(?<port>:\d+)?/";
Console.WriteLine();
Console.Write("Enter a URL for data parsing: ");
string url = Console.ReadLine();
Regex urlExpression = new Regex(urlPattern, RegexOptions.Compiled);
Match urlMatch = urlExpression.Match(url);
Console.WriteLine("The Protocol you entered was " +
urlMatch.Groups["proto"].Value);
Console.WriteLine("The Port Number you entered was " +
urlMatch.Groups["port"].Value);
運行上面的常式時,如果為它輸入一個沒有連接埠號碼的URL,你將會注意到程式不輸入任何組的匹配值。這是因為輸入的文本與Regex根本不匹配。當輸入與Regex不匹配時,顯然就不能夠利用任何命名的組來抽取有意義的資料。如果為上面的常式輸入一個帶連接埠號碼並且與Regex匹配的URL,程式產生的輸出將如下所示:
Enter a URL for data parsing: http://server.com:2100/home.aspx
The Protocol you entered was http
The Port Number you entered was :2100