作為文本處理的利器——Perl語言對正則表達式的最強大支持起到了重要的作用,正因為如此,許多其他語言在加入正則表達式引擎的時候都會或多或少的兼顧perl風格的正則表達式,開發出相應的引擎。本人使用perl語言處理文本有一些時間,同時也有幾年php開發的經歷,像php就有兼容perl的正則表達式引擎,其對應的正則表達式函數就是以p為前綴,如preg_replace、preg_match、preg_split。.NET
類庫當然也提供了正則表達式的支持,位於System.Text.RegularExpressions命名空間下的Regex類封裝了所有正則表達式的屬性和使用方法。本文以C#語言詳細敘述一下.NET類庫下的這個Regex類,可以發現所有的語言對正則表達式的支持都是萬變不離其宗,以類比推理的方式學習非常好。
使用過正則表達式的朋友都知道,正則表達式就是指定一個規則去處理一些復雜的文本(如果是簡單的處理可以使用一般語言內置的字符串處理函數就可以了,而且效率會更好)。這樣需要達到的效果無非就是用一個模式去替換字符串中的特定項為另一特定項、用一個模式去匹配文本中感興趣的部分內容、用一個特殊的模式去拆分文本。
構造函數:用於構造一個正則表達式對象,源碼的聲明如下:
其中聲明為public的構造函數是可以直接使用的,前者使用一個正則表達式字符串構造,後者使用正則表達式字符串和表達式選項構造對象。其中正則表達式選項RegexOptions是一個枚舉類型,用於設置正則表達式的模式修正,C#的這個選項有如下項目:
Multiline —— 將字符串視為多行,“.”就不能匹配換行符(掩碼為2)
Singleline—— 將字符串視為單行,“.”就可以匹配換行符(掩碼為16)
IgnorePatternWhitespace —— 忽略模式表達式中的非轉義空白,並啟用#表示的注釋(掩碼為32)
None —— 不設置選項(掩碼為0)
IgnZ喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcmVDYXNlIKGqoaoguvbC1NfWt/u0rtbQtcS089Ch0LSjqNHawuvOqjGjqQpSaWdodFRvTGVmdCChqqGqIL2rxKzIz7XEtNPX89bB09K1xMvRy/e4xM6qtNPT0tbB1/OjqNHawuvOqjY0o6kKQ29tcGlsZWQgoaqhqiC9q9X91PKx7bTvyr2x4NLrzqqzzNDyvK+jrL/J0tS807/s1MvQ0MvZtsijrLWryse74dT2vNPG9LavyrG85KOo0drC686qOKOpCkN1bHR1cmVJbnZhcmlhbnQgoaqhqiC69sLU0+/R1NbQtcTH+NPy0NSy7tLso6jR2sLrzqo1MTKjqTxicj4KCkV4cGxpY2l0Q2FwdHVyZSChqqGqINa4tqjT0NCntcSytrvxvfbOqtDOyr3OqiAoPzxuYW1lPi4uLikgtcTP1Mq9w/zD+7vyseC6xbXE1+mjrMq5tcPOtMP8w/u1xNSywKi6xb/J0tSz5LWxt8eytrvx1+mjqNHawuvOqjSjqQpFQ01BU2NyaXB0IKGqoaogzqqx7bTvyr3G9NPDt/u6zyBFQ01BU2NyaXB0ILXE0NDOqqOs1rvE3NPrSWdub3JlQ2FzZaGiTXVsdGlsaW5lus1Db21waWxlZNGhz+7Su8bwyrnTw6Oo0drC686qMjU2o6kKyc/K9tGhz+62vMrHyrnTw9Hawuu3vcq9tOa0orXEo6zS8rTLtuC49tGhz+7RodTxtcTKsbry1rG908q508OwtM670+uhsA=="”操作符連接起來即可。
匹配(Match):使用模式進行匹配的時候,.NET提供了IsMatch和Match以及Matches三個函數,第一個返回布爾值用來表示是否匹配成功,第二個則是返回匹配得到的結果Match對象,包含了匹配的結果內容,第三個則是返回一個Match對象的集合,包含了所有匹配的對象。上述函數的所有聲明如下:
IsMatch提供了一個對輸入字符串進行匹配和指定起始位置匹配,同時也提供了對應的靜態函數,用於省去構造對象的麻煩,直接傳入模式進行匹配。使用如下代碼得到的結果如下圖。
string text = @"12345qwert";
if (Regex.IsMatch(text, @"[\d]+"))
{
Console.WriteLine("success");
}
else
{
Console.WriteLine("fail");
}
Match函數也是同樣的提供了輸入字符串匹配,和指定起始位置開始匹配,或者同事指定匹配長度。對應的靜態版本類似。匹配成功返回的是一個Match對象,包含了如下信息:包含的匹配信息Capture、匹配得到的對應的分組信息Group,Capture包含了匹配得到的字符串Value、長度Length和在源字符串中的起始位置Index,Group則擁有組名稱、是否成功Success,同時Match對象包含了NextMatch屬性用於只想下一個匹配得到的Match對象(如果有多個匹配成功項的話),還有Result方法用一個字符串去替換當前匹配到的字符串。Match函數僅返回匹配到的第一個分組,也就是分組0,整個正則表達式匹配到的整體。
Matches函數則是同樣提供了輸入字符串和指定起始位置開始,返回匹配得到的所有Match對象集合。
string text = @"12345qwert67890";
Regex rg = new Regex( @"(?[\d])\d+");
if (rg.IsMatch(text,0))
{
MatchCollection mts = rg.Matches(text,0);
foreach(Match mt in mts )
{
Console.WriteLine("success:" + mt.Value);
}
}
else
{
Console.WriteLine("fail");
}
替換(Replace):其實在Match函數中也提供了Result方法用來替換匹配項,但是功能不夠充分,以下是Regex類中的替換方法:
替換方法Replace方法可以直接對輸入文本替換成給定的文本,也有指定替換次數和起始位置。同時可以使用MatchEvaluator對象進行替換,此對象使用Replace單詞匹配到的Match對象為參數的一個委托,對每個匹配項進行替換。對於簡單的替換可以直接使用字符串參數替換匹配項以及指定替換次數或者起始位置,但是對於復雜的匹配則要使用MatchEvaluator委托進行,可以參考http://www.dotnetperls.com/regex-replace。
分割(Split):分割為找到匹配項後以此階段源字符串,返回字符數組。定義如下:
這個方法的定義比較簡單,就是找到匹配項然後從此字符串拆分獲取拆分的結果,同時可以指定拆分的數組元素個數。測試如下:
string text = @"12345qwert67890";
Regex rg = new Regex( @"(?[\d])\d+");
string [] strArr = rg.Split(text,10);
foreach(string str in strArr )
{
Console.WriteLine("success:{0}", str);
}
從上述圖中結果可以看出,對於有分組的時候,是按照源字符串中的位置順序進行匹配都進行拆分。
除上述內容外,.NET的Regex類還提供了如下方法:
Unescape / Escape—— 轉換輸入字符串中的任何轉義字符 / 轉換普通字符為轉義字符
CompileToAssembly —— 將一個或多個指定的Regex 對象編譯為命名程序集
GroupNameFromNumber / GroupNumberFromName —— 對命名過的分組得到組號或者相反操作
GetGroupNames / GetGroupNumbers —— 返回匹配到的多組匹配項的組號或組名