qregexp括号匹配_转:Qt的正则表达式和QRegExp
考慮一下我們經(jīng)常遇到的問題,比如gemfield想從青島之光讀書(www.civilnet.cn/book)中找一個(gè)關(guān)鍵的電話號碼,通常第一步就是將書中所有的電話號碼查找出來放在手邊。那么怎么擬定查詢條件呢?電話的格式有如下幾種:
01088888888
010 88888888
010-88888888
88888888
0532-88888888
0534-8888888
88888888beijing
qingdao88888888
…………
省略號的意思是格式的種類有很多種,但也有更多種明顯就不是電話類型。這種情況下如何擬定我們的查詢條件呢。如果面面俱到的話,代碼中得多少次if或者switch分支呢。
Gemfield此刻是多么的希望有一個(gè)語句能夠簡單的描述上述所有可能的格式。這或許就是正則表達(dá)式的來歷。正則表達(dá)式的英文原意是:Regular Expression。Regular Expression的“Regular”一般被譯為“正則”、“正規(guī)”、“常規(guī)”。此處的“Regular”即是“規(guī)則”、“規(guī)律”的意思,Regular Expression即“描述某種規(guī)則的表達(dá)式”之意。
來看看gemfield如何一步步實(shí)現(xiàn)這個(gè)想法。
我們可以用
ddd-dddddddd或者ddddddddwwwwwww
來分別描述類似于010-88888888和88888888beijing這樣的例子。
這里,d表示所有可能出現(xiàn)的數(shù)字:0、1、2、3、4…… 9;w表示所有可能出現(xiàn)的字母:a、b、c、d……z。
但有時(shí)我們在這個(gè)位置上明確的限定就是’w’這個(gè)字母,而非代表所有字母的w,那怎么辦呢?上面的舉例肯定會帶來混淆。我們借助反斜杠/來實(shí)現(xiàn):
/d/d/d-/d/d/d/d/d/d/d/d或者/d/d/d/d/d/d/d/d/w/w/w/w/w/w/w
這樣就能區(qū)分w到底是代表所有字母,還是僅僅代表w本身這個(gè)字母。不過看起來就有點(diǎn)丑陋了,這么長,輸錯(cuò)或者看錯(cuò)的個(gè)數(shù)怎么辦?gemfield可以使用下面的寫法來使其變得簡潔:
/d3-/d8或者/d8/w7
但問題又來了,我們這里出現(xiàn)的3是表示前面的數(shù)字出現(xiàn)3次,而非3本身,后面的8、7等數(shù)字同理。怎么辦呢?gemfield可以這樣寫:
/d{3}-/d{8}或者/d{8}/w{7}
這里{}的意義和反斜杠/差不多。都是明確告訴你,w不是w,3不是3。:-D
但很明顯,有的電話號是不加區(qū)號的,比如010-88888888寫作88888888。這樣,就不是/d{3}-/d{8}了,而是/d{8}。或許你可以寫作:
/d{8}或者/d{3}-/d{8}
但“或者”不可能成為程序語言中的關(guān)鍵字的,沒有編譯器會認(rèn)識他。怎么辦?我們想到了程序中有個(gè)運(yùn)算符意思和“或者”相似,它就是| 。gemfield可以寫作:
/d{8} | /d{3}-/d{8}
但怎么看怎么都像少個(gè)東西,看起來混在一起分辨不清。我們想到了圓括號:
(/d{8})|(/d{3}-/d{8})
用圓括號括起來就表示一個(gè)整體了,這里的意思就是說,有2組模式,其中的哪一種都可以。傳統(tǒng)上,?這個(gè)符號(問號)可以用來表示某項(xiàng)是可選的。這樣的話,上面的表達(dá)式可以寫作:
(/d{3}-)?(/d{8})
這樣就表示前面的那一組(/d{3}-)是可選的,也即既可以有,也可以不要,這剛好表達(dá)了gemfield的本意。由于還有010 88888888這種形式,我們還要考慮空格的可選,對于空格,我們可以用/s來表示。表達(dá)式修正如下:
(/d{3})?(-)?/s?(/d{8})
但是電話號碼010 88888888中間的空格在輸入的時(shí)候也許多輸了一個(gè),比如
10 88888888,那怎么辦呢?我們用*來表示0個(gè)、1個(gè)、2個(gè)或者多個(gè)。修正如下:
(/d{3})?(-)?/s*(/d{8})
但是,似乎好像電話不都像北京一樣,有8個(gè)數(shù)字(除了區(qū)號),大多數(shù)中國城市還是7個(gè)呢。所以這個(gè)數(shù)量也必須是可選的。我們可以擴(kuò)展一下:
(/d{3})?(-)?/s*(/d{7,8})
這樣就表示電話號碼是7個(gè)或者8個(gè),也就是大于等于7,小于等于8。
好了,雖然上面的演化對于嚴(yán)謹(jǐn)?shù)恼Z法來說沒有什么意義,但有了這個(gè)思路,就可以認(rèn)識我們的QregExp了,歡迎來到Qt的正則表達(dá)式——QregExp。
****************************************************
正則表達(dá)式由語句、數(shù)量、界定符三者組成。
語句是最簡單的,由[]括起來一個(gè)完整的子語句。如[ABCD] 匹配字母A或B或C或D,而[A-Z]表示26個(gè)大寫的英文字母。
A{1,26}匹配1個(gè)、2個(gè)、3個(gè)……26個(gè)字母A;
[0-9]{1,2}匹配0~99,但同時(shí)也匹配ab34、a34b等;
^[0-9]{1,2},匹配34bc、26abcd,只要數(shù)字前面別有其他東西;
[0-9]{1,2}$ 匹配ab65、aaaaa56,只要數(shù)字后面別有其他東西;
^[0-9]{1,2}$ 只能是2位數(shù)字了。
但是^一旦出現(xiàn)在方括號中就不一樣了。它表示“不包含”。
例如:[^abc]匹配所有的東西,除了a或b或c。
+表示至少出現(xiàn)一次,如([abc]+)表示a或者b或者c至少出現(xiàn)一次。
至于*、?等界定符的意思,和gemfield文中初始部分的推理是一個(gè)意思。
******************************************************
而QregExp這個(gè)類是怎樣使用這些regexp呢,gemfield總結(jié)大致有2種情況,這兩種情況剛好是事物的兩面。第一種是“檢索”類的。看個(gè)例子:
******************************************************
str = "CIVILNET Corporation/tcivilnet.cn/tGELE";
QString company, web, country;
rx.setPattern("^([^/t]+)/t([^/t]+)/t([^/t]+)$");
if (rx.indexIn(str) != -1) {
company = rx.cap(1);
web = rx.cap(2);
country = rx.cap(3);
}
******************************************************
正如上面這個(gè)代碼片段所揭示的,indexIn和cap這兩個(gè)函數(shù)是比較常用的,至于具體的含義,可以閱讀Qt在線文檔:http://www.civilnet.cn/book/embedded/GUI/Qt_assistant/index.php
第二種是“禁止”類的,比如一個(gè)QlineEdit里禁止輸入一些東西,比如郵箱名禁止輸入&等。這個(gè)是用QRegExpValidator 來實(shí)現(xiàn)的,該類接收一個(gè)QregExp型的正則表達(dá)式作為實(shí)例化時(shí)的參數(shù):
**********************************************************
QRegExp rx("-?//d{1,3}");
QValidator *validator = new QRegExpValidator(rx, this);
QLineEdit *edit = new QLineEdit(this);
edit->setValidator(validator);
************************************************************
分享到:
2011-06-20 14:01
瀏覽 825
評論
總結(jié)
以上是生活随笔為你收集整理的qregexp括号匹配_转:Qt的正则表达式和QRegExp的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 种植牙价格多少钱一颗啊?
- 下一篇: mysql如何设置多节点_详细介绍Mys