正則表達式


表1.常用的元字符
代碼 說明
. 匹配除換行符以外的任意字符
\w 匹配字母或數字或下劃線或漢字
\s 匹配任意的空白符
\d 匹配數字
\b 匹配單詞的開始或結束
^ 匹配字符串的開始
$ 匹配字符串的結束

一個網站如果要求你填寫的QQ號必須爲5位到12位數字時,可以使用:^\d{5,12}$

這裏的{5,12}和前面介紹過的{2}是類似的,只不過{2}匹配只能不多不少重複2次{5,12}則是重複的次數不能少於5次,不能多於12次,否則都不匹配。

因爲使用了^$,所以輸入的整個字符串都要用來和\d{5,12}來匹配


表2.常用的限定符
代碼/語法 說明
* 重複零次或更多次
+ 重複一次或更多次
? 重複零次或一次
{n} 重複n次
{n,} 重複n次或更多次
{n,m} 重複n到m次


   \(?0\d{2}[) -]?\d{8}       //  “(”和“)”也是元字符,後面的分組節裏會提到,所以在這裏需要使用轉義

這個表達式可以匹配幾種格式的電話號碼,像(010)88886666,或022-22334455,或02912345678等。我們對它進行一些分析吧:首先是一個轉義字符\(,它能出現0次或1次(?),然後是一個0,後面跟着2個數字(\d{2}),然後是)-空格中的一個,它出現1次或不出現(?),最後是8個數字(\d{8}

  注意: 此表達式也能匹配010)12345678(022-87654321這樣的“不正確”的格式


分枝條件指的是有幾種規則,如果滿足其中任意一種規則都應該當成匹配,具體方法是用|把不同的規則分隔開。看例子:

0\d{2}-\d{8}|0\d{3}-\d{7}這個表達式能匹配兩種以連字號分隔的電話號碼:一種是三位區號,8位本地號(如010-12345678),一種是4位區號,7位本地號(0376-2233445)

\(0\d{2}\)[- ]?\d{8}|0\d{2}[- ]?\d{8}這個表達式匹配3位區號的電話號碼,其中區號可以用小括號括起來,也可以不用,區號與本地號間可以用連字號或空格間隔,也可以沒有間隔。你可以試試用分枝條件把這個表達式擴展成也支持4位區號的。


可以用小括號來指定子表達式(也叫做分組)

一個正確的IP地址:((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)


表3.常用的反義代碼
代碼/語法 說明
\W 匹配任意不是字母,數字,下劃線,漢字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非數字的字符
\B 匹配不是單詞開頭或結束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou這幾個字母以外的任意字符
   注意:  大小寫區分

後向引用

使用小括號指定一個子表達式後,匹配這個子表達式的文本(也就是此分組捕獲的內容)可以在表達式或其它程序中作進一步的處理。默認情況下,每個分組會自動擁有一個組號,規則是:從左向右,以分組的左括號爲標誌,第一個出現的分組的組號爲1,第二個爲2,以此類推。

呃……其實,組號分配還不像我剛說得那麼簡單:

  • 分組0對應整個正則表達式
  • 實際上組號分配過程是要從左向右掃描兩遍的:第一遍只給未命名組分配,第二遍只給命名組分配--因此所有命名組的組號都大於未命名的組號
  • 你可以使用(?:exp)這樣的語法來剝奪一個分組對組號分配的參與權.
後向引用用於重複搜索前面某個分組匹配的文本。例如,\1代表分組1匹配的文本

例:

\b(\w+)\b\s+\1\b可以用來匹配重複的單詞,像go go, 或者kitty kitty。這個表達式首先是一個單詞,也就是單詞開始處和結束處之間的多於一個的字母或數字(\b(\w+)\b),這個單詞會被捕獲到編號爲1的分組中,然後是1個或幾個空白符(\s+),最後是分組1中捕獲的內容(也就是前面匹配的那個單詞)(\1)。


你也可以自己指定子表達式的組名。要指定一個子表達式的組名,請使用這樣的語法:(?<Word>\w+)(或者把尖括號換成'也行:(?'Word'\w+)),這樣就把\w+的組名指定爲Word了。要反向引用這個分組捕獲的內容,你可以使用\k<Word>,所以上一個例子也可以寫成這樣:\b(?<Word>\w+)\b\s+\k<Word>\b

使用小括號的時候,還有很多特定用途的語法。下面列出了最常用的一些:

表4.常用分組語法
分類 代碼/語法 說明
捕獲 (exp) 匹配exp,並捕獲文本到自動命名的組裏
(?<name>exp) 匹配exp,並捕獲文本到名稱爲name的組裏,也可以寫成(?'name'exp)
(?:exp) 匹配exp,不捕獲匹配的文本,也不給此分組分配組號
零寬斷言 (?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp後面的位置
(?!exp) 匹配後面跟的不是exp的位置
(?<!exp) 匹配前面不是exp的位置
註釋 (?#comment) 這種類型的分組不對正則表達式的處理產生任何影響,用於提供註釋讓人閱讀

(?=exp)也叫零寬度正預測先行斷言,它斷言自身出現的位置的後面能匹配表達式exp。比如\b\w+(?=ing\b),匹配以ing結尾的單詞的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.時,它會匹配singdanc

(?<=exp)也叫零寬度正回顧後發斷言,它斷言自身出現的位置的前面能匹配表達式exp。比如(?<=\bre)\w+\b會匹配以re開頭的單詞的後半部分(除了re以外的部分),例如在查找reading a book時,它匹配ading


貪婪與懶惰

當正則表達式中包含能接受重複的限定符時,通常的行爲是(在使整個表達式能得到匹配的前提下)匹配儘可能多的字符。以這個表達式爲例:a.*b,它將會匹配最長的以a開始,以b結束的字符串。如果用它來搜索aabab的話,它會匹配整個字符串aabab。這被稱爲貪婪匹配。

有時,我們更需要懶惰匹配,也就是匹配儘可能少的字符。前面給出的限定符都可以被轉化爲懶惰匹配模式,只要在它後面加上一個問號?。這樣.*?就意味着匹配任意數量的重複,但是在能使整個匹配成功的前提下使用最少的重複。現在看看懶惰版的例子吧:

a.*?b匹配最短的,以a開始,以b結束的字符串。如果把它應用於aabab的話,它會匹配aab(第一到第三個字符)ab(第四到第五個字符)

爲什麼第一個匹配是aab(第一到第三個字符)而不是ab(第二到第三個字符)?簡單地說,因爲正則表達式有另一條規則,比懶惰/貪婪規則的優先級更高:最先開始的匹配擁有最高的優先權——The match that begins earliest wins。

表5.懶惰限定符
代碼/語法 說明
*? 重複任意次,但儘可能少重複
+? 重複1次或更多次,但儘可能少重複
?? 重複0次或1次,但儘可能少重複
{n,m}? 重複n到m次,但儘可能少重複
{n,}? 重複n次以上,但儘可能少重複

本文摘自以下鏈接,更詳細的說明。

http://www.cnblogs.com/deerchao/archive/2006/08/24/zhengzhe30fengzhongjiaocheng.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章