正則表達式概要_第1頁
正則表達式概要_第2頁
正則表達式概要_第3頁
正則表達式概要_第4頁
正則表達式概要_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、基礎(chǔ)(摘自正則表達式之道) 正則表達式由一些普通字符和一些元字符(metacharacters)組成。普通字符包括大小寫的字母和數(shù)字,而元字符則具有特殊的含義,我們下面會給予解釋。 在最簡單的情況下,一個正則表達式看上去就是一個普通的查找串。例如,正則表達式"testing"中沒有包含任何元字符,它可以匹配"testing"和"123testing"等字符串,但是不能匹配"Testing"。 要想真正的用好正則表達式,正確的理解元字符是最重要的事情。下表列出了所有的元字符和對它們的一個簡短的描述。 元字符 描述.點

2、 匹配任何單個字符。例如正則表達式r.t匹配這些字符串:rat、rut、r t,但是不匹配root。 $匹配行結(jié)束符。例如正則表達式weasel$ 能夠匹配字符串"He's a weasel"的末尾 但是不能匹配字符串"They are a bunch of weasels."匹配一行的開始。例如正則表達式When in能夠匹配字符串"When in the course of human events"的開始,但是不能匹配"What and When in the"*匹配0或多個正好在它之前的那個字符。例

3、如正則表達式 .* 意味著能夠匹配任意數(shù)量的任何字符。比如<T>.*</T> 可以匹配<T>不管是什么</T> 這是引用符,用來將這里列出的這些元字符當(dāng)作普通的字符來進行匹配。例如正則表達式$被用來匹配美元符號,而不是行尾,類似的,正則表達式.用來匹配點字符,而不是任何字符的通配符。 c1-c2 c1-c2匹配括號中的任何一個字符。例如正則表達式raout匹配rat、rot和rut,但是不匹配ret??梢栽诶ㄌ栔惺褂眠B字符-來指定字符的區(qū)間,例如正則表達式0-9可以匹配任何數(shù)字字符;還可以制定多個區(qū)間,例如正則表達式A-Za-z可以匹配任何大小寫

4、字母。另一個重要的用法是“排除”,要想匹配除了指定區(qū)間之外的字符也就是所謂的補集在左邊的括號和第一個字符之間使用字符,例如正則表達式269A-Z 將匹配除了2、6、9和所有大寫字母之外的任何字符。A1357B-Xbd*fg B289g-y3,7+1456A-N?*< >匹配詞(word)的開始(<)和結(jié)束(>)。例如正則表達式<the>能夠匹配字符串"for the wise"中的"the",但是不能匹配字符串"otherwise"中的"the"。注意:這個元字符不是所有的軟件都

5、支持的。( )將 ( 和 ) 之間的表達式定義為“組”(group),并且將匹配這個表達式的字符保存到一個臨時區(qū)域(一個正則表達式中最多可以保存9個),它們可以用 1 到9 的符號來引用。|將兩個匹配條件進行邏輯“或”(Or)運算。例如正則表達式(him|her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。注意:這個元字符不是所有的軟件都支持的。+匹配1或多個正好在它之前的那個字符。例如正則表達式9+匹配9、99、999等。注意:這個元字

6、符不是所有的軟件都支持的。?匹配0或1個正好在它之前的那個字符。注意:這個元字符不是所有的軟件都支持的。i i,j匹配指定數(shù)目的字符,這些字符是在它之前的表達式定義的。例如正則表達式A0-93 能夠匹配字符"A"后面跟著正好3個數(shù)字字符的串,例如A123、A348等,但是不匹配A1234。而正則表達式0-94,6 匹配連續(xù)的任意4個、5個或者6個數(shù)字字符。注意:這個元字符不是所有的軟件都支持的。最簡單的元字符是點,它能夠匹配任何單個字符(注意不包括換行符)。假定有個文件test.txt包含以下幾行內(nèi)容: he is a rat he is in a rut the food

7、 is Rotten I like root beer 我們可以使用grep命令來測試我們的正則表達式,grep命令使用正則表達式去嘗試匹配指定文件的每一行,并將至少有一處匹配表達式的所有行顯示出來。命令 grep r.t test.txt 要想匹配行首的字符要使用抑揚字符()有時也被叫做插入符。例如,想找到text.txt中行首"he"打頭的行,你可能會先用簡單表達式he,但是這會匹配第三行的the,所以要使用正則表達式he,它只匹配在行首出現(xiàn)的h。 有時候指定“除了×××都匹配”會比較容易達到目的,當(dāng)抑揚字符()出現(xiàn)在方括號中時,它表示“排

8、除”,例如要匹配he ,但是排除前面是t or s的情形(也就是the和she),可以使用:sthe。 可以使用方括號來指定多個字符區(qū)間。例如正則表達式A-Za-z匹配任何字母,包括大寫和小寫的;正則表達式A-Za-zA-Za-z* 匹配一個字母后面接著0或者多個字母(大寫或者小寫)。當(dāng)然我們也可以用元字符+做到同樣的事情,也就是:A-Za-z+ ,和A-Za-zA-Za-z*完全等價。但是要注意元字符+ 并不是所有支持正則表達式的程序都支持的。關(guān)于這一點可以參考后面的正則表達式語法支持情況。 要指定特定數(shù)量的匹配,要使用大括號(注意必須使用反斜杠來轉(zhuǎn)義)。想匹配所有10和100的實例而排除1

9、和 1000,可以使用:101,2,這個正則表達式匹配數(shù)字1后面跟著1或者2個0的模式。在這個元字符的使用中一個有用的變化是忽略第二個數(shù)字,例如正則表達式03, 將匹配至少3個連續(xù)的0。 簡單的例子這里有一些有代表性的、比較簡單的例子。 vi 命令作用:%s/ */ /g把一個或者多個空格替換為一個空格:%s/ *$/去掉行尾的所有空格:%s/ /在每一行頭上加入一個空格:%s/0-90-9* /去掉行首的所有數(shù)字字符:%s/baeiog/bug/g將所有的bag、beg、big和bog改為bug。 :%s/t(aou)g/h1t/g將所有tag、tog和tug分別改為hat、hot和hut(

10、注意用group的用法和使用1引用前面被匹配的字符)中級的例子例1 將所有方法foo(a,b,c)的實例改為foo(b,a,c)。這里a、b和c可以是任何提供給方法foo()的參數(shù)。也就是說我們要實現(xiàn)這樣的轉(zhuǎn)換: 之前 之后 foo(10,7,2) foo(7,10,2) foo(x+13,y-2,10) foo(y-2,x+13,10) foo( bar(8), x+y+z, 5) foo( x+y+z, bar(8), 5) 下面這條替換命令能夠?qū)崿F(xiàn)這一魔法: :%s/foo(,*),(,*),()*)/foo(2,1,3)/g 現(xiàn)在讓我們把它打散來加以分析。寫出這個表達式的基本思路是找出

11、foo()和它的括號中的三個參數(shù)的位置。第一個參數(shù)是用這個表達式來識別的:(,*),我們可以從里向外來分析它: , 除了逗號之外的任何字符 ,* 0或者多個非逗號字符 (,*) 將這些非逗號字符標(biāo)記為1,這樣可以在之后的替換模式表達式中引用它 (,*), 我們必須找到0或者多個非逗號字符后面跟著一個逗號,并且非逗號字符那部分要標(biāo)記出來以備后用。 現(xiàn)在正是指出一個使用正則表達式常見錯誤的最佳時機。為什么我們要使用,*這樣的一個表達式,而不是更加簡單直接的寫法,例如:.*,來匹配第一個參數(shù)呢?設(shè)想我們使用模式.*來匹配字符串"10,7,2",它應(yīng)該匹配"10,&quo

12、t;還是"10,7,"?為了解決這個兩義性(ambiguity),正則表達式規(guī)定一律按照最長的串來,在上面的例子中就是"10,7,",顯然這樣就找出了兩個參數(shù)而不是我們期望的一個。所以,我們要使用,*來強制取出第一個逗號之前的部分。 這個表達式我們已經(jīng)分析到了:foo(,*),這一段可以簡單的翻譯為“當(dāng)你找到foo(就把其后直到第一個逗號之前的部分標(biāo)記為1”。然后我們使用同樣的辦法標(biāo)記第二個參數(shù)為2。對第三個參數(shù)的標(biāo)記方法也是一樣,只是我們要搜索所有的字符直到右括號。我們并沒有必要去搜索第三個參數(shù),因為我們不需要調(diào)整它的位置,但是這樣的模式能夠保證我們只

13、去替換那些有三個參數(shù)的foo()方法調(diào)用,在foo()是一個重載(overoading)方法時這種明確的模式往往是比較保險的。然后,在替換部分,我們找到foo()的對應(yīng)實例,然后利用標(biāo)記好的部分進行替換,是把第一和第二個參數(shù)交換位置。 例2 假設(shè)有一個CSV(comma separated value)文件,里面有一些我們需要的信息,但是格式卻有問題,目前數(shù)據(jù)的列順序是:姓名,公司名,州名縮寫,郵政編碼,現(xiàn)在我們希望講這些數(shù)據(jù)重新組織,以便在我們的某個軟件中使用,需要的格式為:姓名,州名縮寫-郵政編碼,公司名。也就是說,我們要調(diào)整列順序,還要合并兩個列來構(gòu)成一個新列。另外,我們的軟件不能接受逗

14、號前后有任何空格(包括空格和制表符)所以我們還必須要去掉逗號前后的所有空格。 這里有幾行我們現(xiàn)在的數(shù)據(jù): Bill Jones, HI-TEK Corporation , CA, 95011 Sharon Lee Smith, Design Works Incorporated, CA, 95012 B. Amos , Hill Street Cafe, CA, 95013 Alexander Weatherworth, The Crafts Store, CA, 95014 . 我們希望把它變成這個樣子: Bill Jones,CA 95011,HI-TEK Corporation Shar

15、on Lee Smith,CA 95012,Design Works Incorporated B. Amos,CA 95013,Hill Street Cafe Alexander Weatherworth,CA 95014,The Crafts Store . 我們將用兩個正則表達式來解決這個問題。第一個移動列和合并列,第二個用來去掉空格。 下面就是第一個替換命令: :%s/(,*),(,*),(,*),(.*)/1,3 4,2/ 這里的方法跟例1基本一樣,第一個列(姓名)用這個表達式來匹配:(,*),即第一個逗號之前的所有字符,而姓名內(nèi)容被用1標(biāo)記下來。公司名和州名縮寫字段用同樣的方法標(biāo)

16、記為2和3,而最后一個字段用(.*)來匹配("匹配所有字符直到行末")。替換部分則引用上面標(biāo)記的那些內(nèi)容來進行構(gòu)造。 下面這個替換命令則用來去除空格: :%s/ t*, t*/,/g 我們還是分解來看: t匹配空格/制表符, t* 匹配0或多個空格/制表符, t*,匹配0或多個空格/制表符后面再加一個逗號,最后, t*, t*匹配0或多個空格/制表符接著一個逗號再接著0或多個空格/制表符。在替換部分,我們簡單的我們找到的所有東西替換成一個逗號。這里我們使用了結(jié)尾的可選的g參數(shù),這表示在每行中對所有匹配的串執(zhí)行替換(而不是缺省的只替換第一個匹配串)。 例3 假設(shè)有一個多字符的

17、片斷重復(fù)出現(xiàn),例如: Billy tried really hard Sally tried really really hard Timmy tried really really really hard Johnny tried really really really really hard 而你想把"really"、"really really",以及任意數(shù)量連續(xù)出現(xiàn)的"really"字符串換成一個簡單的"very"(simple is good!),那么以下命令: :%s/(really )(really

18、 )*/very / 就會把上述的文本變成: Billy tried very hard Sally tried very hard Timmy tried very hard Johnny tried very hard 表達式(really )*匹配0或多個連續(xù)的"really "(注意結(jié)尾有個空格),而(really )(really )* 匹配1個或多個連續(xù)的"really "實例。 不同工具中的正則表達式OK,你已經(jīng)準(zhǔn)備使用RE(regular expressions,正則表達式),但是你并準(zhǔn)備使用vi。所以,在這里我們給出一些在其他工具中使用

19、RE的例子。另外,我還會總結(jié)一下你在不同程序之間使用RE可能發(fā)現(xiàn)的區(qū)別。 當(dāng)然,你也可以在Visual C+編輯器中使用RE。選擇Edit->Replace,然后選擇"Regular expression"選擇框,F(xiàn)ind What輸入框?qū)?yīng)上面介紹的vi命令:%s/pat1/pat2/g中的pat1部分,而Replace輸入框?qū)?yīng)pat2部分。但是,為了得到vi的執(zhí)行范圍和g選項,你要使用Replace All或者適當(dāng)?shù)氖止ind Next and Replace(譯者按:知道為啥有人罵微軟弱智了吧,雖然VC中可以選中一個范圍的文本,然后在其中執(zhí)行替換,但是總之不

20、夠vi那么靈活和典雅)。常用的正則表達式主要有以下幾種: 匹配中文字符的正則表達式: u4e00-u9fa5 評注:匹配中文還真是個頭疼的事,有了這個表達式就好辦了哦 獲取日期正則表達式:d4年|-|.d1-12月|-|.d1-31日? 評注:可用來匹配大多數(shù)年月日信息。 匹配雙字節(jié)字符(包括漢字在內(nèi)):x00-xff 評注:可以用來計算字符串的長度(一個雙字節(jié)字符長度計2,ASCII字符計1) 匹配空白行的正則表達式:ns*r 評注:可以用來刪除空白行 匹配HTML標(biāo)記的正則表達式:<(S*?)>*>.*?</>|<.*? /> 評注:網(wǎng)上流傳的版本

21、太糟糕,上面這個也僅僅能匹配部分,對于復(fù)雜的嵌套標(biāo)記依舊無能為力 匹配首尾空白字符的正則表達式:s*|s*$ 評注:可以用來刪除行首行尾的空白字符(包括空格、制表符、換頁符等等),非常有用的表達式 匹配Email地址的正則表達式:w+(-+.w+)*w+(-.w+)*.w+(-.w+)* 評注:表單驗證時很實用 匹配網(wǎng)址URL的正則表達式:a-zA-z+:/s* 評注:網(wǎng)上流傳的版本功能很有限,上面這個基本可以滿足需求 匹配帳號是否合法(字母開頭,允許5-16字節(jié),允許字母數(shù)字下劃線):a-zA-Za-zA-Z0-9_4,15$ 評注:表單驗證時很實用 匹配國內(nèi)電話號碼:d4-d7,8|d3-d8 評注:匹配形式如 0511 - 4405222 或 021 - 87888822 匹配騰訊QQ號:1-90-94, 評注:騰訊QQ號從1000 0 開始 匹配中國郵政編碼:1-9d5(?!d) 評注:中國郵政編碼為6位數(shù)字 匹配身份證:d17d|X評注:中國的身份證為15位或18位 匹配ip地址:(20-4d|250-

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論