十五、C++正則表達式

正則表達式的核心在于用一個字符串(模式串)來描述、匹配一系列符合某個句法規(guī)則的字符串(待匹配串)。正則表達式中可以包含普通或者特殊字符,特殊字符可以影響正則表達式的解釋。可以用在線網(wǎng)站驗證寫的正則表達式是否能正確匹配,如:http://www.jsons.cn/reg/

正則表達式中常用的特殊字符

表15-1 按次數(shù)匹配子表達式和首尾字串匹配

? */+/?三個字符可以合并記憶為匹配子表達式0+、1+、01次;
? ^/$可以合并記憶為匹配字符串頭尾。

?次數(shù)區(qū)間表示(續(xù)表15-1)

? 次數(shù)區(qū)間匹配,匹配區(qū)間內(nèi)的數(shù)值次。

?非貪婪匹配和轉(zhuǎn)義(續(xù)表15-1)

? ?在特殊字符后表示為非貪婪匹配,即取特殊字符表示的最小的條件;
? \為轉(zhuǎn)義字符,用于轉(zhuǎn)義表達式中的特殊字符,即匹配特殊字符本身。

按集合內(nèi)容匹配(續(xù)表15-1)

? 除了字符范圍的表達外,“[]”集合中的每一個元素(而非每一個子集,要注意)都會被匹配。

“或匹配”和子表達式的表示(續(xù)表15-1)

? 使用字符“|”需要注意的是其類似邏輯運算“||”的分支優(yōu)先特點,即出現(xiàn)表達式值為真就返回。
? 括號表示子表達式可以方便獲取匹配結(jié)果(存至smatch)。

“\”加字母形式的特殊字符匹配(續(xù)表15-1)

? 其中最常用的是【\d、\D、\w、\W】,分別用于匹配(非)數(shù)字以及(非)數(shù)字和字母。

C++的正則表達式庫——regex
regex類表示一個正則表達式。表15-2列出了regex支持的操作。
表15-2 regex類的操作

定義regex時指定的標(biāo)志(續(xù)表15-2)

在C++語言中,通常需要將一個正則表達式存儲在一個字符串字面值常量中再賦值給regex對象,其中需要留意對特殊字符本身的轉(zhuǎn)義。
特別注意(記?。?,正則表達式中的一個“\”,在C++字面值常量中需要2個“\”來表示。例如:為了匹配“.”,因其可以表示特殊字符,因此需要對其轉(zhuǎn)義,應(yīng)該寫作“\.”,但是“\”本身具有轉(zhuǎn)義的含義,因此又應(yīng)該對“\”再轉(zhuǎn)義,所以最終得到的字面值常量字符串為“\\.”。

C++正則表達式的匹配、查找、替換
C++提供了regex_match函數(shù)實現(xiàn)正則表達式的匹配功能;提供了regex_search函數(shù)實現(xiàn)正則表達式的查找功能;提供了regex_replace函數(shù)實現(xiàn)正則表達式的替換功能。具體解釋見表15-3。

??match是整個、search是部分,返回匹配到與否的布爾值。

子表達式與smatch
????????正則表達式可以捕獲到匹配的子串。這通常通過“( )”模式串和smatch類型來實現(xiàn)。
????????通常把“(?)”構(gòu)成的表達式稱為子表達式。smatch是一個容器類型,它存儲的元素類型是ssub_match,負責(zé)保存子表達式匹配的結(jié)果,它通常會傳遞給regex_search或regex_match函數(shù)作為參數(shù)。
????????smatch 對象除了提供匹配整體的相關(guān)信息外,還提供訪問每個子表達式匹配結(jié)果的能力。子表達式的匹配結(jié)果是按位置來訪問的。第一個子匹配位置為0,表示整個模式對應(yīng)的匹配,然后按子表達式在整個表達式中出現(xiàn)的順序給出每個子表達式對應(yīng)的匹配。表15-4列舉了smatch類型支持的操作。

? m.prefix()和m.suffix()一般只在regex_search中使用(regex_match是匹配整個序列)。

????????在regex_replace中的參數(shù)fmt中,可以將“$”和一個非負整數(shù)連接起來,來表示匹配的子串。例如:fmt中“$1”表示匹配的第一個子串...特殊的是,“$0”表示匹配的整個字符串。

regex迭代器
有時可能需要逐一遍歷待匹配串中與某個模式串匹配的所有字串,如果此時僅用regex_search會使代碼顯得冗余。因此C++提供了regex迭代器類型sregex_iterator來獲得所有匹配的子串,它被綁定到一個輸入序列和一個regex對象上。初學(xué)階段,可以認(rèn)為sregex_iterator指向的就是調(diào)用regex_search函數(shù)匹配成功后得到的smatch對象。這種迭代器操作如表15-5所示。

? 由于sregex_iterator指向的就是ssub_match對象,因此獲取了匹配成功的sregex
_iterator,你就可以通過迭代器調(diào)用表15-4中列舉的smatch對象支持的操作。
下例展示了如何使用sregex_iterator實現(xiàn)類似stringstream的字符串分割: