程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 正則表達式簡介

正則表達式簡介

編輯:關於C++

正則表達式簡介

翻譯:NorthTibet

有些新手對正則表達式不是很熟悉,有必要在此作一簡單回顧。如果你是正則表達式高手,可以不用看這一部分。

正則表達式是描述字符串集的字符串。例如,正則表達式“Mic*”描述所有包含“Mic”,後跟零個或多個字符的字符串。Mickey、Microsoft、Michelangelo 或 Mic 本身都是例子。句號“.”匹配任何字符,“+”類似“*”,但至少要一個字符,所以“Mic+”匹配前述所有除“Mic”以外的串。[a-z]指一個匹配范圍,所以[a-zA-Z_0-9]匹配字母、數字或下劃線。Regex 稱之為單詞字符,可以將它寫成“\w”。所以“\w+”匹配至少有一個字符的單詞字符序列——換句話說,叫 C 符號(C tokens)。那麼這樣一來,幾乎所有的C 符號都不能以數字開頭,因此,下面這個正則表達式是正確的:“^[a-zA-Z_]\w*$”。專用字符“^”意思是“以...開始”(除非它位於某個范圍之內,這時它的意思是“非”),“$”意思是“結尾”,那麼“^[a-zA-Z_]\w*$”意思就是:以字母或下劃線開始的字母、數字或下劃線字符串。

正則表達式在對輸入進行有效性驗證時非常有用。\d 匹配數字,{n}匹配重復n次,於是 ^5\d{15}$ 匹配5開頭的16位數字,也即是說 MasterCard 信用卡號碼。那 ^[45]\d{15}$ 就是Visa 卡號,它以4開頭。你可以用大括弧對表達式進行分組,下面是個測試。這個表達式描述的是什麼呢?

^\d{5}(-\d{4}){0,1}$

提示:{0,1} 意思是重復0次或1次(可以縮寫成問號 ?)。想出來了嗎?該表達式意思是:五個數字後重復0次或1次(破折號後跟四個數字)。它匹配 02142和98007-4235,但不匹配 3245 或 2345-98761。這也就是美國的郵政編碼。大括弧將 ZIP+4 部分分組,所以{0,1}修飾符將應用於整個分組。

以上我僅淺嘗即止地說明了正則表達式能做什麼。我還沒提到替換,由於我沒有具體資料,所以不敢描述在 Unicode 中會怎麼樣。但你能感覺到正則表達式有多麼強大。多年來它們乃 UNIX 的中流砥柱,並且在Web 編程和 Perl 這樣的語言中更臻完善,其對 HTML 的操作幾乎完全是對文本的處理。正則表達式在 Windows 中一直沒有得到充分使用,直到 .NET 框架面世,它才正式成為 Windows 家族的一員。

框架 Regex 類

.NET 框架用 Regex 類實現正則表達式,並有三個支持類:Match、Group 和 Capture (參見 Figure A)。典型情況下,你創建 Regex 並用輸入串調用 Regex::Match 來獲得第一個 Match,或用 Regex::Matches 來獲取所有匹配:

Regex *r = new Regex("\b\w+\b"); MatchCollection* mc = r->Matches("abc ,_foo ,<& mumble7"); for (int i=0; i<mc->Count; i++) { Match *m = mc->Index(i); Console.WriteLine(m->Value); }

這將顯示“abc”,“foo”和“mumble7”,每個匹配在一行。這個例子引入了一個專門的字符 \b,所謂錨或原子零寬度斷言,就像 ^(開始)和$(結尾)。\b 指定某個單詞的邊界,所以“\b\w+\b”意思是用單詞分隔的一個或多個單詞字符。

Figure A Regex 類

正則表達式中的每個括弧表達式都構成一個 Group。Regex::Groups 返回作為集合的 Groups,它決不會是空,因為整個正則表達式本身即是一組。Groups很重要,因為它們使你進行邏輯 OR 匹配,如“(ying|yong)”,它們使你將限定符應用到子表達式,並讓你吸取匹配的單獨部分。正文的 Figure 1 中我的 RegexTest 程序運行後用郵編為例顯示分組。

在所有函數中最強大的函數要數 Regex::Replace,它使得正則表達式的威力驚人地強大。和許多開發人員一樣,過去在多次傳遞字符串到多行編輯控件之前,我常常不得不手工將 “\n” 轉換為“\r\n”,但使用 Regex::Replace,這個操作簡直易如反掌。

s = Regex::Replace(s,"\n","\r\n");

Regex::Match 和 Replace 具備靜態重載,所以你可以不用創建對象,以快速使用正則表達式。我最喜歡的 Regex::Replace 重載之一是帶有一個委托參數,使你能用過程代碼動態計算替換文本——參見正文中那個有趣的例子。

一些警告:每一種正則表達式的實現是有不太一樣的。例如,在 Perl 中,{,1}是{0,1}的速記版,而微軟的老大們不是那樣做的。要當心一些微小的差別。權威的 .NET Regex 資料請參考 MSDN 庫中的 “Regular Expressions as a Language(http://www.vckbase.com/library/en-us/cpguide/html/cpconregularexpressionsaslanguage.asp)”。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved