您好,登錄后才能下訂單哦!
先來看一個例子,要求寫一段代碼,實現如下功能:
從標準輸入中讀取一行字符串, 從中讀取所有郵箱的格式;
對于這個問題,用傳統的方式是可以解決的:
我們可以用解析字符串的方式實現,需要遍歷一遍獲取的字符串,讀取其中關鍵的幾個字符 “.” "@" ".com" 和其中的相關順序;
C++11支持正則表達式,利用它可以避免重復造輪子;
代碼:
#include <iostream> #include <string> #include <regex> int main() { std::string line; std::regex email(R"(\w+@(\w+\.)+\w+)"); while ( getline(std::cin, line) ) { std::smatch matches; auto current = cbegin(line); auto last = cend(line); while ( current != last ) { if (regex_search(current, last, matches, email)) { std::ssub_match match = matches[0]; current = match.second; std::cout << "[ " << match.str() << " ]" << std::endl;
} else { break; } } } }
——————————————————————
正文:
一、正則表達式介紹
正則表達式(regular expression) 是一種描述字符序列的方法,是一種極其強大的計算工具。C++11中新增了這一特性,在 C++正則表達式庫(RE庫)中。
PS:RE庫,定義在頭文件 "regex"內,命名空間:std;
正則表達式組件:
regex : 表示有一個正則表達式的類;
regex_match : 將一個字符序列與一個正則表達式匹配;
regex_search : 尋找第一個與正則表達式匹配的子序列;
regex_replace : 使用給定格式替換一個正則表達式;
sregex_iterator : 迭代器適配器,調用regex_search 來遍歷一個string中所有匹配的子串;
smatch : 容器類,保存在string中搜索的結果;
ssub_match : string中匹配的子表達式的結果;
接下來簡單介紹幾個常用的組件:
regex類:
表示一個正則表達式。除了初始化和賦值操作,還支持其他的一些操作(后面介紹);
regex_match方法:
確定一個給定字符序列與一個給定regex對象是否完全匹配,返回true/false,如果匹配到,將匹配到的內容保存起來;
segex_search方法:
確定一個給定字符序列與一個給定regex對象是否匹配,只要有部分匹配,就返回true,如果匹配到,將匹配到的部分保存起來;
以上兩個方法均有2個重載版本,分別為:
(seq, m, r, mft) (seq, r, mft) /* seq: 待查找的字符串序列, 可以是一個std::string,或表示范圍的一對迭代器,或一個指向空字符結尾的字符數組的指針 m: smatch對象,用來保存匹配結果的相關細節 r: regex對象,匹配的類型 mft: (可選) regex_constants::match_flag_type類型,它們會影響匹配過程 (后述) */
二、使用RE庫
從上面那幾個組件的介紹,我們得知:
1、regex類型的對象就是存放要匹配字符串的指定格式,而這個格式就是所謂的"正則表達式"了。
默認的正則表達式語言是 ECMAScript,接下來介紹一些常用的ECMAScript語法
1.1、模式[[::alpha:]]
匹配任意字母
1.2、符號 "+"
一個或多個,比如 "[[::alpha:]]+" 表示希望匹配一個或多個字母
1.3、符號"*"
零個或多個,比如 "[[::alpha:]]+" 表示希望匹配零個或多個字母
2、smatch類型的對象,用來保存所匹配到的字符串1
接下來做一個小練習:
有一個英文單詞的拼寫規則:"i除非排在c之后,否則必須在e之前";
比如: "freind"、"theif"就不符合這一拼寫規范,而"recepit" "receive"則符合;
現在要求寫一個程序,從標準輸入中讀取一行字符串,找出這些不符合規則的英文單詞。
代碼:
// 查找不在字符c之后的字符串ei int main() { std::string pattern("[^c]ei"); /* “[^c]” : 希望匹配不是c的字符 "[^c]ei" :想要匹配的上述字符后接ei的字符串 */ // 需要包含pattern的整個單詞 pattern = "[[:alpha:]]*" + pattern + "[[:alpha:]]*"; /* 前后追加 "[[:alpha:]]*" 表示:與"[^c]ei"模式匹配的完整字符串 */ std::regex r(pattern); // 構造一個用于查找模式的regex std::smatch results; // 定義一個對象保存搜索結果 // 定義一個string保存與模式匹配的文本,以及不匹配的文本 std::string test_str; while (getline(std::cin, test_str)) { // 用r在test_str中查找與pattern匹配的子串 if (regex_search(test_str, results, r)) { std::ssub_match result = results[0]; std::string ret_str = "[ " + results.str() + " ]"; std::cout << ret_str << std::endl; } } return 0; }
_________________________________________________________
指定regex對象的選項:
當我們定義一個regex對象,或對一個regex對象調用assign為其賦予新值時,可以指定一些標志來影響regex如何操作
regex
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。