今天細看了一下正則表達式,記錄之
正則表達式類
QRegExp類使用正則表達式提供了模式匹配
一正則表達式(regexp)用來在文中的子串中進行模式匹配,在很多環境下都經常用到,例如:
1、validation 檢驗數據有效性,正則表達式可以用來檢驗字串是否符合某個規則,比如是一個整形或者不包含空格
2、查找 正則表達式與簡單的字串比較相比提供了更強大的模式匹配,比如:匹配mail、letter、或者correspondence中的任意一個,但不是email、mailman、mailer和letterbox中的任何一個等等
3、查找替換 正則表達式可以使用不同的字串來替換與正則表達式匹配的字串,比如使用&替換所有的&,但&後邊已經緊跟amp的除外
4、字符串分割 正則表達式可以用來標識字符串的分割點,比如將字符串以tab分割。
這裏只是簡單的介紹,至於qt中正則語言的詳細描述,實例和函數等參見文檔本身。
QRegExp是基於Perl 正則表達式語言的,它完全支持Unicode,它同樣可以像shells命令中的函數樣使用,在QregExp中的語法規則可以使用setPatternSyntax()函數修改,尤其是,匹配語法可以設置爲QregExp::FixedString,意思是要匹配的模式以簡單的字符串看待,這樣,特殊字符(比如:/反斜槓)都不會逃掉。
一本好的關於正則表達式的書<Mastering Regular Expressions>(第三版) 作者 Jeffrey E.F.Friedl .ISBN 0-596-52812-4
介紹:
正則表達式是由表達式,量詞和聲明斷言構成,最簡單的表達式是一個字符,如:x或5,一個表達式也可以是由中括號包含起來的字符集,[ABCD]將匹配A、B、C、D其中任意一個,同樣我們也可以寫成[A-D],要匹配所有的大寫英文字符就可以使用表達式[A-Z].
量詞制訂了表達式必須匹配的次數,x{1,1}匹配一個並且僅僅是一個x,x{1,5}匹配一組連續的x字符,最多不超過5個(可以是,x,xx,xxx,xxxx,xxxxx)
注意,一般的表達式不能用來檢查括號或者標籤的相對應字符,例如,如果<b>沒有被嵌套,正則表達式可以匹配開放的<b>標籤html<b>和其關閉</b> ,反之如果<b>被嵌套了,那麼同樣的正則表達式將會匹配錯誤的關閉</b>,
比如html片段: <b>bold<b>bolder</b></b>
第一個<b>會匹配第一個</b>,這是錯誤的,如果嵌套層次固定且可知時可以寫出括號或標籤正確匹配的正則表達式,否則不能。
假如你想寫一個匹配0-99整數的正則表達式,,至少需要一個數字,故你寫表達式[0-9]{1,1},該表達式匹配一個數字,匹配範圍爲0-9,要匹配到99,將最大發生次數提高到2,所以正則表達式變爲[0-9]{1,2},該表達式滿足開始的0-99整數的需求,但同樣也匹配其再子字符串中間的案例,如果想將整數視爲一個完成字符串來匹配,就必須使用固定聲明^和$,當^作爲正則表達式的第一個字符時,意味着匹配字符必須是字符串的開始,同理當$爲一個正則表達式的最後一個字符時,意味着正則表達式必須匹配到字符串的結尾(即完整字符串匹配),
此時正則表達式變成了^[0-99]{1,2}$,注意^和$在表達式中但不匹配字符。
如果你在別處看過關於正則表達式的,可能與現在這裏所說的不太一樣,這是因爲字符集合和一些量詞太常見了,故用其它特殊 符號來表示[0-9]可以使用\d代替,量詞只匹配一次{1,1}可以使用其本身代替(即可以省略不寫),x{1,1}和x是一樣的,所以0-99就可以寫成^\d{1,2}$
,還可以寫成^\d\d{0,1}$,例如以數字開頭的字符串,後邊緊跟0或者一個數字的字符串,在實際中通常可以寫成^\d\d?$, 其中?是{0,1}的簡寫方式,即發生0次或1次,?使得一個表達式可選,正則表達式^\d\d?$意味着從字符串開頭開始,匹配一個數字,緊接着是0或1個數字,然後就是字符串結尾。
要寫一個匹配”mail”,”letter”,”correspondence”其中之一但不匹配包含前面三個詞的字符串,比如”email”,”mailman”,”mailer”,和”letterbox”,正則表達式,首先,要匹配”mail”,完整的表達式是m{1,1}a{1,1}i{1,1}l{1,1},因爲單個字符自動匹配{1,1}所以,簡單表達式爲mail,即爲m後緊跟a,a後緊跟i,i後緊跟l,
使用|表示或,故表達式mail|letter|correspondence 意味着匹配mail或letter或correspondence,
同樣email也會匹配,爲阻止匹配不想要的詞,我們必須告之匹配一個單詞邊界 的開始與結尾,首先使用括號將其括起來(mail|letter|correspondence).表示正則表達式的一部分,在複雜的正則吧表達式中這樣可以更明瞭其構成,這樣也可以告訴我們是哪個詞被匹配了,強制匹配一個詞的開始與結尾,使用\b,表達式變爲\b(mail|letter|correspondence)\b,現在表達式的意思就是:匹配單詞邊界,緊接着是圓括號內的表達式,然後是單詞邊界,\b聲明一個位置匹配,不是字符,單詞邊界爲任何非-單詞字符,比如,空格,新行(換行)或字符串的開始和結尾。
如果想使用html中的&來替換普通的&,正則表達式匹配單個的&,但是,表達式同樣也匹配已經使用html替換的&中的’&’,我們只是想匹配那些’&’後緊跟的不是amp;的’&’
就需要使用否定斷言,(?!__),該表達式可以寫成&(?!amp;)
如果想計數’Eric’和’Eirik’在字符串中的個數,兩個方法可行,\b(Eric|Eirik)\b和\bEi?ri[ck]\b
稍後將實現上述中的一些實例。
字符集中的字符和縮寫
對象 意義
C 單個字符標識其本身,除非它在正則表達式中有特殊意義
\c 特殊字符本身,
\a 匹配ASCII bell(BEL,0x07)
\f 匹配ASCII form feed(FF,0x0C)
\n 匹配ASCII 行(LF,0x0A,Unix newline)
\r 匹配ASCII 回車(CR,0x0D)
\t 匹配ASCII 水平tab鍵(HT,0x09)
\v 匹配ASCII 豎直tab鍵(VT,0x0B)
\xhhhh 匹配Unicode字符十六進制數hhhh(0x0000 -0xFFFF)
\0ooo 匹配八進制數ooo(0-0377)
. 匹配任意字符(包括newline)
\d 匹配數字(Qchar::isDiagit())
\D 匹配非數字
\s 匹配空格字符(Qchar::isSpace())
\S 匹配非空格字符
\w 匹配單詞字符(Qchar::isLetterOrNumber(),Qchar::isMark(),或者’_’)
\W 匹配非單詞字符
\n 匹配第幾個backreference 例如\1,\2
C++編譯器轉義反斜槓,在正則表達式中包含\,需要寫成\\,若要匹配反斜槓字符本身,鍵入四次\\\\.
字符集
中括號字符集表示匹配其中的任意一個字符,
1、[abc]表示其中的任意一個,[^abc]表示除a,b,c外任意一個字符
2、[W-Z]表示 ‘W’,’X’,’Y’,’Z’中任意一個字符
量詞
1、E? 表示0個或一個E, ?表示前面是一個可選項,等價於E{0,1}
2、E+ 表示至少一個E,E+等價於E{1,}
3、E* 表示0個或者多個E,相當於E{0,}
4、E{n} 表示n個E
5、E{n,} 表示至少n個E
6、E{,m} 表示最多m個E
7、E{n,m} 表示E的個數在n和m之間
Tag+ 表示至少一個g,(Tag)+表示至少一個Tag
圓括號可以讓我們將元素組織到一起,以便確定數量和捕獲他們,例如,我們有正則表達式mail|letter|correspondence 匹配一個字符串,我們直到其中一個被匹配了,但不知道是哪一個,使用圓括號就可以,使用(mail|letter|correspondence)匹配字符串”I sent you some email” ,我們可以使用cap()或者capturedText()函數獲取匹配字符串,這裏是”mail”:
在正則表達式本身就可以使用捕獲字符串,以索引1開始使用反引用文本,同cap()函數一樣,例如,在字符串中的重複單詞使用正則表達式\b(\w+)\W+\1\b
意味着匹配一個單詞邊界,緊跟一個或多個單詞字符,緊跟一個或多個非單詞字符,然後是(前面中括號中的)一個或多個單詞字符
如果我們使用圓括號僅僅時分類歸組而不是捕獲,我們可以使用非捕獲語法格式,比如(?:green|blue),在這個例子中我們匹配green或者blue,但是我們沒有捕獲匹配項,所以我們只直到是否有顏色匹配,但不知道具體匹配的是哪個顏色。
當然非捕獲模式比捕獲模式效率要高。